codeforces 556B. Case of Fake Numbers 解题报告

题目链接:http://codeforces.com/problemset/problem/556/B

题目意思:给出 n 个齿轮,每个齿轮有 n 个 teeth,逆时针排列,编号为0 ~ n-1。每按一次 button,每个齿轮都会有且仅有一个活动的tooth,对于偶数编号的齿轮,它下一个活动tooth是紧挨着当前tooth的逆时针方向的那个;而奇数编号的齿轮,下一个活动tooth是顺时针的那个。给出每个齿轮的活动tooth,问通过按下有限次的button,问能不能得到一个0,1,...,n-2,n-1的序列。

  离校第一场!果然惨不堪言~~~~

  犯了些低级错误,输入输出问题= =;然后问题复杂化了,复杂化就算了,连算法都错了。输入的时候用了int,然后转为char保存,以便strcmp比较。。。然后计算新的tooth的时候又转回int。。。。这样做的错误就是输入从int变为char,而算出新的tooth的位置时会比较不了。

  例如有这样的序列:

15
2  14  4  1  6  3  8  5  10  7  12  9  14  11  1

codeforces  556B. Case of Fake Numbers  解题报告

ref:0 ~ n-1 的 char

s: 输入的原始序列转化为 char

  然后计算新位置的时候,

  奇数齿轮计算公式:x = (x-1+n) % n;

  偶数齿轮计算公式:x = (x+1+n) % n

  问题就出在x上,留意ref的10, 11,之后的位置,不是对应的阿拉伯数字来的,是字符,而公式是针对数字来计算新的tooth位置的。这就会导致(列举10次)以下的情况:

  codeforces  556B. Case of Fake Numbers  解题报告

  可想而知就是 呵呵呵 了。。。。= =

最后我就踏踏实实用 int 数组来做了,血与泪的教训!一步一步模拟,不要想太多。

  这里讲一下循环结束条件,只需要试验1000次就可以了,因为对于每一只齿轮,活动tooth是周而复始的,试验1000次就能把一个齿轮的每个tooth都试遍,其实所有齿轮也就是1000种序列情况嘛~~~同步的哟。

 #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
using namespace std; const int maxn = + ;
int a[maxn]; int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif // ONLINE_JUDGE int n;
while (scanf("%d", &n) != EOF) { for (int i = ; i < n; i++) {
cin >> a[i];
}
bool flag = true;
int cnt = ;
while (cnt < maxn) {
flag = true;
cnt++;
for (int i = ; i < n; i++) {
if (a[i] != i) {
flag = false;
break;
}
}
if (flag) {
break;
} else {
for (int i = ; i < n; i++) {
if (i & ) {
a[i] = (a[i] - + n) % n;
}
else {
a[i] = (a[i] + ) % n;
}
}
}
}
printf("%s\n", flag ? "Yes" : "No");
}
return ;
}
上一篇:NYOJ 77 开灯问题


下一篇:百度地图JavaScript API V1.5初级开发工具类