HDU-5668-Circle(中国余数定理/解同余方程组)
2016-04-26 20:33
218 查看
Circle
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 320 Accepted Submission(s): 102
[align=left]Problem Description[/align]
Satiya
August is in charge of souls.
He
finds n
souls,and lets them become a circle.He ordered them to play Joseph Games.The souls will count off from the soul1.The
soul who is numbered k
will be taken out,and will not join in the game again.
Now
Satiya August has got the sequence in the Out Ordered,and ask you the smallest
k.If
you cannot give him a correct answer,he will kill you!
[align=left]Input[/align]
The
first line has a number T,means testcase number.
Each
test,first line has a number n.
The
second line has n
numbers,which are the sequence in the Out Ordered**(The person who is out at
aith
round was numbered i)**.
The
sequence input must be a permutation from 1
to n.
1≤T≤10,2≤n≤20.
[align=left]Output[/align]
For
each case,If there is a eligible number k,output
the smallest k,otherwise,output”Creation
August is a SB!”.
[align=left]Sample Input[/align]
1 7 7 6 5 4 3 2 1
[align=left]Sample Output[/align]
420
[align=left]Source[/align]
BestCoder Round #80
考虑对给定的出圈序列进行一次模拟,对于出圈的人我们显然可以由位置,编号等关系得到一个同余方程 一圈做下来我们就得到了n个同余方程 对每个方程用扩展欧几里得求解,最后找到最小可行解就是答案. 当然不要忘了判无解的情况.
#include <iostream> #include <cstdio> #include <vector> #include <algorithm> #include <cstring> #include <string> #include <cmath> #include <set> #include <map> #include <queue> #include <stack> using namespace std; const int MAXN = 107; int num[MAXN]; long long mod[MAXN],b[MAXN]; // k(%mod)==b bool vis[MAXN]; void egcd(long long a, long long b, long long &d, long long &x, long long &y) { if (!b)d=a,x=1,y=0; else { egcd(b, a%b, d, y, x); y -= x*(a / b); } } long long CRT(int n) { long long M=mod[1],B=b[1],x,y,d; for (int i=2; i<=n; i++) { egcd(M,mod[i],d,x,y); if ((b[i]-B)%d)return -1; x=(b[i]-B)/d*x%(mod[i]/d); B+=x*M; M=M/d*mod[i]; B%=M; } return (B+M)%M?(B+M)%M:M; } int main() { int T; cin>>T; while(T--) { int n,p; memset(vis,0,sizeof(vis)); scanf("%d",&n); for(int i=1; i<=n; ++i) { scanf("%d",&p); num[p]=i; } int j=1,k; for(int i=1; i<=n; ++i) { k=1; while(j!=num[i]) { if(!vis[j])++k; j=j%n+1; } vis[num[i]]=1; mod[i]=n-i+1; b[i]=k%mod[i]; } int flag=CRT(n); if(flag==-1)cout<<"Creation August is a SB!\n"; else cout<<flag<<endl; } return 0; }
相关文章推荐
- 二.I/O模型
- NOIP - 关押罪犯
- bat
- ListView出现数据重复的问题的解决
- c++实验4—星形图
- 剑指offer(31):最小的k个数
- #include <NOIP2010 Junior> 三国游戏 ——using namespace wxl;
- 关于输入两个值后输出最大公约数和最小公倍数
- div中img显示问题
- 【数据结构】优先级队列的实现(适配器模式)
- iOS:在使用Cocoapods安装shareSDK时出现的link路径错误
- 轻松解决mscorsvw.exe进程CPU占用高的问题
- poj 2488 A Knight's Journey
- android shape浅析
- Holding Bin-Laden Captive! hdoj 1085 (母函数初学,其他简便方法)
- 每日站立会议(九)
- iOS 写入文件保存数据的方式
- 数质数
- LeetCode 49. Group Anagrams
- SASS如何实现PX转REM