小t的游戲
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 235 Accepted Submission(s): 130
Problem Description
小t有點神經質,喜歡發明一些稀奇古怪的游戲,比如說左手和右手打架就是他發明的。
這個周末,小t又發明了一個有趣的硬幣游戲:小t手裡有6枚硬幣,他把硬幣分成了兩堆,一左一右並排堆放,一堆2個,一堆4個。然後他開始從這兩個堆中各取出1個硬幣,再組成一個新的堆放在最右邊。用(2,4)表示初始兩堆,於是作下抽象,第一次操作後(2,4)變成了(1,3,2)。小t繼續操作,他從這三堆中繼續各取出1個硬幣,組成新堆放到最右邊。於是(1,3,2)變成了(0,2,1,3),去掉空堆,變成(2,1,3)。小t繼續進行以上操作並去除空堆,(2,1,3)變成了(1,2,3)。這時,小t發現如果繼續做同樣的動作,分堆的硬幣不會再有變化了,一直都是(1,2,3)狀態,也就是陷入了循環節為1的循環。
小t突發奇想,他想知道:如果知道硬幣的分堆數,和每堆硬幣的個數,執行“每次從已有的每一堆硬幣中取出1個硬幣,湊成新堆”的操作,用(a,b,c,d,….)表示分堆狀態(其中a,b,c,d…每個字母都是正整數),分堆狀態是否會陷入循環,如果陷入循環,循環節又是多少呢。
Input
輸入有很多組case,每組case
第一行一個正整數n (n<65536),表示硬幣分為多少堆
第二行有n個整數,每個數k<65536,表示每堆有多少個硬幣,每個數後面都有一個空格。
Output
如果分堆狀態陷入循環,輸出分兩行,第一行輸出yes,第二行輸出一個整數表示循環節長度。
否則輸出就一行no。
Sample Input
2
2 4
2
2 3
Sample Output
yes
1
yes
3
循環節次數與總和有關。
若恰好是前N個連續數字的和,則循環節為1;
如7可以寫成1,2,4;
8可以寫成1,1,2,4;
9可以寫成1,1,3,4;
末尾的四每次減少一,正好四次
#include"stdio.h"
#include"string.h"
#define N 1000005
int mark[N];
int main()
{
int i,n,ans,sum;
while(scanf("%d",&n)!=-1)
{
sum=0;
while(n--)
{
scanf("%d",&i);
sum+=i;
}
for(i=1;i<=sum;i++)
{
if(sum==(i+1)*i/2) //循環節為1,如1,2,3,4;
{
ans=1;
break;
}
else if(sum<(i+1)*i/2)
{
ans=i;
break;
}
}
printf("yes\n%d\n",ans);
}
return 0;
}