UVA133 救济金发放

mac2022-06-30  23

入门书习题 方法: 这是一个环,我先把环的所有值都置为1,如果之后选到了这个值,那么就把它置为0,以后再碰到这个值,就跳过,去算下一个。 PS:

调试过程中发现需要注意一下数组下标的问题,我这里数组下标是从1开始到n结束的,所以当我模为0的时候,需要把它调整成n的值,否则就会有bug;默认环是按照逆时针顺序摆放的,那么在处理顺时针旋转的时候,需要一点小trick。(书上自定义了个函数,原来顺时针和逆时针也就是步长为1和-1的区别。。。萌新表示很难受)

AC代码:

#include<bits/stdc++.h> using namespace std; const int maxn=25; char a[maxn]; int main(){ int n,k,m; while(cin>>n>>k>>m&&(m||n||k)){ for(int i=1;i<=n;i++){ //先把所有值都置为1 a[i]=1; } a[0]=a[n]; int p=0,q=n+1,N=n; while(n){ int k1=k,m1=m; while(k1--){ //处理逆时针转 p=(p+1)%N; if(p==0)p=N;//如果模的答案是0,那么把它调成n的值 if(a[p]==0){ //如果到达了选到过的值,那么就跳过这个值 k1+=1;continue; } } while(m1--){ //处理顺时针转 q=(q+(N-1))%N;//因为是个环,下标-1和下标+(n-1)是等价的(因为反正都要取模的) if(q==0)q=N; if(a[q]==0){ m1+=1;continue; } } a[p]=a[q]=0;//把两者置为0(选到过了),然后n-2 n-=2; if(p==q){ //如果两者到了同一点,那么就给n加一个1 n++; printf("=",p); if(n)cout<<","; if(!n)cout<<endl; } else { printf("==",p,q); if(n)cout<<","; if(!n)cout<<endl; } } } return 0; }
最新回复(0)