난이도:(보통)
우리의 친구 현우는 오늘도 어김없이 열심히 비트코인 시세표를 보고 있다!
그러다가 어느날 새로운 종목이 나타났는데
이 비트코인은 신기하게도 지금 1001원이였으면 1시간뒤에는 1002원 또 1시간이지나면 999원
(문제가 잘못표기됬었네요 헣;)
또 한시간이 지나면 1003원 이된다고한다 (1+2-3+4-5...)
현우는 이 이랬다 저랫다 하는 비트코인을 1000원에사서
최고의 이득을 보려고 할 때 몇 시간 뒤에 팔아야 최고이득을 볼 수 있을까?
(단 이 비트코인의 가격이 0원 미만이 되어버리면 비트코인 자체가 없어져 버린다고 한다)
우리의 친구 현우를 위해 우리가 대신 구해줘 보자!
33개의 풀이가 있습니다.
1000원짜리 비트코인을 사고 2시간씩 시간을 확인하면... 2시간당 1원씩 사라지게 되는 모양이 됨.
2-3 => -1 => 999원 (-1)
4-5 => -1 => 998원 (-2)
6-7 => -1 => 997원 (-3)
...
1000-1001 => 500원 (-500)
...
1998-1999 => 1원 (-999)
2000-2001 => 0원 (-1000)
2002-2003 => -1원 (-1001) # 0미만이면 비트코인 사라짐
결국 2001을 뺄 때에 정확히 0원을 찍고 최고 가격은 2002원이 됨. 더하는 숫자가 2였을때는 1시간째였으니 2002시간에는 2001을 뺌.
결론적으로 얼마를 넣던지간에 n+2 만큼의 이익을 얻을 수 있으며 빼야하는 적정타이밍은 2n+1시간임.
1000원 -> 2001시간 후에 빼면 1002원의 이익
파이썬 코드 확인
def algo(n):
print("원금:", n)
count = 0
for i in range(2, 1000000):
count += 1
if i%2: #홀수라면
if n - i < 0:
break
n -= i
else : # 짝수라면
n += i
print("잔액: {} 걸린 시간: {}".format(n, count - 1))
algo(1000)
algo(5000)
algo(10000)
# Output
#원금: 1000
#잔액: 2002 걸린 시간: 2001
#원금: 5000
#잔액: 10002 걸린 시간: 10001
#원금: 10000
#잔액: 20002 걸린 시간: 20001
def count(price):
hour, maximum, max_hour, plus = 1, -1, 0, True
while price > 0 :
if plus : price += hour
else : price -= hour
if price > maximum : max_hour = hour
hour += 1
plus = not plus
return max_hour
def p_m(n):
sum=0
b=True
vsr="+"
for i in range(1,n+1):
sum=eval('sum{}i'.format(vsr))
if b:
b=False
vsr='+'
else :
b=True
vsr='-'
return sum
print(1000+p_m(2004))
2003을넣으면 0이되어서그다음숫자인 2004라고넣었는데 긴했는데 너무수동적이네요;; 어떻게하면 시간을입력으로안주고 할수있을까요? (사실문제를만들다가 바꾸어서;;다시갈아없고하기 너무망설여지더라고욬..그래서 그냥이렇게 그리고 사실
m=1
while 1000+p_m(m)>=0:
m+=1
print(1000+p_m(m))
으로 구할순있어도 시간복잡도가 엄청나버려져서;;; )
ans=1000
j=2
max=0
def plusminus(num1, num2, char):
if char == "p":
return num1+num2
else:
return num1-num2
while ans >= 1 :
if j%2 == 0:
ans=plusminus(ans,j,"p")
else:
ans=plusminus(ans,j,"m")
if ans > max:
max=ans
j+=1
print (ans, j)
파이썬3
이 비트코인은 신기하게도 지금 1000원이였으면 1시간뒤에는 1002원 또 1시간이지나면 999원 또 한시간이 지나면 1003원 이된다고한다 (1+2-3+4-5...)
def fn(money, hour):
outcome = money
for i in range(1, hour+1):
if i % 2 == 1:
outcome += i+1
else:
outcome -= i+1
return outcome
money = 1000
h = 1 #시간
while True:
money = fn(1000, h)
if money < 0:
break
h += 1
print(h-1)
# 2001
price = 1000
count = 1
last_price = price
while price >= 0:
count += 1
if count % 2 == 0:
change = count
else:
change = -count
last_price = price
price += change
print("{} {}".format(count-1,last_price))
def x():
i = 2
while 1:
yield i*((-1)**i)
i += 1
p,cnt = 1000,0
y = x()
while 1:
tmp = p+next(y)
if tmp < 0: break
p = tmp
cnt += 1
print(p,cnt)
문제가 여전히 이상하네요
bitcoin = 1001
count = 1
while(bitcoin > 0):
if count%2 == 0:
bitcoin -= count
count += 1
print(bitcoin)
print(str(count-1),'시간')
else:
bitcoin += count
count += 1
print(bitcoin)
print(str(count-1), '시간')
//C언어
#include <stdio.h>
int main(void)
{
int i = 1;
int bitcoin = 1000;
while (1)
{
if (i == 1) {
bitcoin += i;
printf("%d\t%d시간뒤\n", bitcoin,i);
}
else if (i % 2 == 0) {
bitcoin += i;
printf("%d\t%d시간뒤\n", bitcoin,i);
}
else {
bitcoin -= i;
printf("%d\t%d시간뒤\n", bitcoin,i);
}
i++;
if (bitcoin == 0) {
puts("");
printf("최고의 이득은 %d시간뒤입니다.", i - 2);
break;
}
}
return 0;
}
money = int(input("deposit money"))
time = 1
# time 은 1씩 올라가는 정수로, 매 time에 대해서 시세가 변동후 존버할지 아니면 매도할지를 정한다.
# 비트코인에 대한 시행은 이 2개 뿐이다.
sign = '존버'
while sign == '존버': # sign은 존버, 떡락
if time%2 == 1:
money_box = money + time
else:
money_box = money - time
# money_box 는 금액 값을 임시로 저장하고, 현 시점에서 매도할지, 존버할지를 판단하여 money 에 해당 값을 저장한다.
if money_box >= 0:
money = money_box
else:
sign = '매수'
time += 1
print(money)
저는 python을 사용하였습니다. 비트코인이 주제이니 최대한 재미있게 코드를 짜보려 하였습니다^^ 언급했다싶이, time ++ -> 현재 시세를 우선 moneybox라는 임시 저장공간에 저장하고, 그대로 가야할지 아니면 팔아야 할지를 판단합니다. 전자의 경우 money에 값을 저장을 하고, 만약 팔아야 한다면 이전 시세가 저장된 money를 다루면 되는것이죠.
time, value = 0, 1000
sign = 1
while value >= 0:
time += 1
value += sign * time
sign = -sign
print(time - 1)
original_Coin=1000
Coin=1000
C=1
Coin = Coin+C
C+=1
hour=1
result =[(Coin,hour)]
Flag=1
while Flag:
if C %2==0:
Coin=Coin+C
C+=1
hour+=1
result.append((Coin,hour))
else:
Coin=Coin-C
C+=1
hour+=1
result.append((Coin,hour))
if Coin ==0:
Flag=0
print(sorted(result,reverse=True)[1][1],':시간이후',abs(original_Coin-sorted(result,reverse=True)[1][0]),'원이득!')
#최소 원금의 1.5배로 회수하고싶다
#잃는 것의 하한선은 다 잃을 때까지
import random
value = 1000
count = 0
while True:
value += random.randint(-10, 10)
count += 1
if value < 0:
print('파산')
break
else:
if value > 1500:
print('{}시간 후에 {}가격으로 팔면 {}이득'.format(count, value, value -1000))
break
C#
문제에서 예시된 금액과 증감치가 일치하지 않습니다. 따라서 증감치가 [2, -3, 4, -5, ...] (즉, 1002원, 999원, 1003원, 998원, ...)이 되는 것으로 이해하고 풀이하였습니다.
구매가격
P0 에 대해 임의 시간 t에서의 코인가격 Pt는 다음과 같이 나타낼 수 있습니다. (Pt는 0과 같거나 큰 정수)
Pt = P0 + SUM{ n = 1..t | (t + 1) * (-1)**(t + 1) }
참고. 이 식으로 계산하면, 시간 t = 2*P0 + 1 일 때, 최고 코인값 2*P0 + 2를 가집니다.
using System;
using System.Linq;
namespace CD177
{
internal class Program
{
private static void Main()
{
int price(int p0, int t)
=> p0 + Enumerable.Range(1, t).Select(i => (i + 1) * (int)Math.Pow(-1, i + 1)).Sum();
int initialPrice = 1000;
int maxPrice = 0;
int time = 0, timeAtMaxPrice = 0;
while (true)
{
time++;
var p = price(initialPrice, time);
if (p < 0) { break; }
if (maxPrice < p)
{
maxPrice = p;
timeAtMaxPrice = time;
}
}
Console.WriteLine(timeAtMaxPrice);
}
}
}
price=1000
priceList=[]
cnt = 1
max = 0
time = 0
while price > 0:
if cnt % 2 == 0 or cnt == 1:
price += cnt
priceList.append(price)
else:
price -= cnt
priceList.append(price)
cnt += 1
for i, account in enumerate(priceList):
if account > max:
max = account
time = i+1
print(time, max)
print(priceList)
존버는 승리한다.
price=1001
h=0
while(price>0):
h+=1
price+=h*(-1)**(h+1)
print('{}시간 후까지 존버하세요 by John Burr Williams'.format(h-1))
파이썬 3.7
money, coin = 1000, 1000
hour = 1
while 1:
if hour == 1:
coin += hour
else:
coin += hour * ((-1) ** hour)
if coin < 0:
print('%d시간 뒤에 팔면 됩니다' % (hour - 1))
break
hour += 1
public class 요랬다조랬다 {
public static void main(String[] args) {
int coin = 1000;
int hour = 0;
int biggestPrice = 0;
ArrayList<Integer> list = new ArrayList<Integer>();
for(int i=1;;i++) {
if(coin<0) {
break;
}
if(i==1) {
hour++;
coin++;
}
else if(i%2==0) {
coin+=i;
hour++;
}
else if(i%2!=0){
coin-=i;
hour++;
}
if(coin>biggestPrice) {
biggestPrice=coin;
list.add(hour);
}
}
System.out.println(list.get(list.size()-1)+"시간 뒤에 팔아야 최고이득입니다.");
}
}
base = 1000
value = 0
Run = True
i = 1
while Run:
if i % 2 != 0:
base += i
#print("value", value)
if base > value:
value = base
else :
base -= i
if base <= 0:
break
else :
i+=1
print(value)
def bit(sm):
t = 1
time = 0
max_sm = sm
while sm >= 0:
t += 1
m = t*(-1) if t%2 != 0 else t
sm += m
if max_sm < sm:
max_sm = sm
time = t-1
return time
if __name__ == '__main__':
sm = 1000
print('{}시간 뒤 최고 이득!!'.format(bit(sm)))
n = int(input())
pasthour= 1
price = []
while n >= 0:
if pasthour%2 == 0:
n = n-pasthour
pasthour += 1
elif pasthour%2 == 1:
n = n+pasthour
pasthour += 1
else:
continue
price.append(n)
price.index(max(price))+1
#파이썬
#제대로 이해하고 푼건지 모르겠습니다.
'''
1시간후 1001
2시간후 999
3시간후 1002
4시간후 998
5시간후 1003
1999시간후 2000
2000시간후 0
2001시간후 2001
2002시간후 -1
'''
#이렇게 이해를 하고 풀었습니다
bitcoin,mark,time=1000,1,0
max_time, max_bitcoin=0,0
while (bitcoin>-1):
time+=1
bitcoin+=mark*time
mark*=-1
print (time, bitcoin)
if bitcoin>max_bitcoin:
max_bitcoin,max_time=bitcoin,time
print (max_time, '시간 후에 비트코인이 ',max_bitcoin)
파이썬3입니다.
문제나 예시가 조금 왔다갔다 하는 것 갔지만 일단
문제의 의도대로 풀었습니다.
n = 1000 #Initial money
t = 0 # elapsed hours
while n>0 :
t += 1
if t == 1 :
n += 1
elif t%2 == 0 :
n += t
elif t%2 != 0 :
n -= t
print(f'Burrow till {t-1} hours.')
#include<stdio.h>
int main()
{
int c=1;
int money=1000;
while(1)
{
if(money<0)
{
printf(">%d",c-2);
break;
}
else if(money>0&&c%2==0)
{
c++;
money=money-c;
}
else
{
c++;
money=money+c;
}
}
return 0;
}
def count(price): hour, maximum, max_hour, plus = 1, -1, 0, True while price > 0 : if plus : price += hour else : price -= hour if price > maximum : max_hour = hour hour += 1 plus = not plus return max_hour
N = 1001
M = 1
while True:
M += 1
if M % 2 == 1:
N -= M
elif M % 2 == 0:
N += M
if N < 0:
print(M-1)
break
cost = 1001
n = 2
count = 0
while cost:
if n % 2 == 0:
cost += n
else:
cost -= n
if cost == 0:
print(count)
n+=1
count +=1
money = 1000
hour = 0
mon_arr=[]
while money>0:
hour +=1
if hour%2==1:
money += hour
mon_arr.append(money)
else:
money -= hour
mon_arr.append(money)
print(mon_arr.index(max(mon_arr))+1)
문제가 이상하지만 +1-2+3-4... 로 풀었어요~ 1시간별 평가금액을 배열화하고 최대가 될떄 index에서 +1 해준값이 수익이 최대화되는 시간이 되게끔 짜봤어요
def bit(a):
b=a
i = 1
time = 0
while a > 0:
if i < 2:
a += i
time +=1
i+=1
print("비트코인 금액 : {0}원, 손익 : {1}".format(a,(a-b)))
print("경과시간 : {0}시간".format(time))
print("---------------------------------")
if i % 2 == 0:
a += i
time +=1
i+=1
elif i % 2 == 1:
a -= i
time +=1
i+=1
if a == 0 :
print("-----비트코인이 폐지되었습니다.-----")
break
print("비트코인 금액 : {0}원, 손익 : {1}".format(a,(a-b)))
print("경과시간 : {0}시간".format(time))
print("---------------------------------")
bit(1000)
using System;
namespace solution
{
class Program
{
static void Main(string[] args)
{
Console.Write("지금 가지고 있는 비트코인은?: ");
int coin = int.Parse(Console.ReadLine());
// 계산 식으로
Console.WriteLine("\n시간: {0}, 최대 코인: {1}", (coin+1) * 2, (coin+1)*2 + 1);
// 일일이 시행
timeForMaxProfit(coin);
}
private static void timeForMaxProfit(int coin)
{
int t = 1;
coin += 1;
while(coin > 0)
{
t++;
if (t % 2 == 0)
coin += t;
else
coin -= t;
}
t--;
Console.WriteLine("\n최고의 이득을 보려고 할 때 {0} 시간 뒤에 팔아야 최고이득 {1}을 봄",t, coin + t + 1);
}
}
}