P1965 夜夜的数据加强 题解
2015-10-09 22:57
381 查看
这是VIJIOS上的一道题,原题的链接https://vijos.org/p/1965
先上代码,用C++写的
这里参考了该题doc写的题解,题解的地址为https://vijos.org/p/1965/solution。如果单纯用doc的暴力方法是不能通过的(能通过第5个测试点,但是后面的测试点不能通过),我另外加了一个优化。
考虑到N比C大很多的情况,这个时候计算fa[i]时取余运算(%i),就不起作用了,可以简化为
fa[i+1] = (fa[i] * a + b) % c(这里i >= c)
在这里只和a和b有关,与x无关,因此可以先枚举a和b,然后检验a和b是否可行,如果可行就进行,接下来枚举x再校验数列i<=c的情况(此时后面不需要校验了)。
另外这个程序要仔细编写,做尽可能的预处理,下面的测试结果可以看到在第5个测试点是很惊险地通过了。
先上代码,用C++写的
# include<iostream> using namespace std; int fa[100001]; int savemod[400][400][400]; int ii[100000]; // a^(i-1) 从1开始使用 int jj[100000]; // 1+a+a^2+a^(i-2) 从1开始使用 bool ans[400][400][400]; int len; int amod[400][400]; // amod[i][j] = i % j; int main() { int x, a, b; int i, j, k; int n, c; cin >> n >> c; for (i = 1; i <= n-1; i++) { cin >> fa[i]; if (fa[i] >= i || fa[i] < 0 || fa[i] >= c) { cout << "Unsuccessful Hack Attempt" << endl; return 0; } } if (n == 1) { for (x = 0; x < c; x++) for (a = 0; a < c; a++) for (b = 0; b < c; b++) cout << x << " " << a << " " << b << endl; return 0; } int tmp; for (i = 0; i < c; i++) for (j = i; j < c; j++) { tmp = (i*j) % c; for (k = 0; k < c - tmp; k++) { savemod[i][j][k] = tmp + k; savemod[j][i][k] = tmp + k; } for (k = 0; k < tmp; k++) { savemod[i][j][c-tmp+k] = k; savemod[j][i][c-tmp+k] = k; } } for (i = 1; i < 400; i++) for (j = 2; j < 400; j++) amod[i][j] = i % j; int s; bool flag = false; if (n - 1 > c) { for (a = 0; a < c; a++) { for (b = 0; b < c; b++) { for (i = n-2; i >= c; i--) { if (savemod[fa[i]][a][b] != fa[i+1]) break; } if (i < c) for (x = 0; x < c; x++) { for (s = savemod[x][a][b],j = 2; j <= c && amod[s][j] == fa[j]; s=savemod[s][a][b], j++); if (j > c) { ans[x][a][b] = true; flag = true; } } } } } else { for (a = 0; a < c; a++) { ii[1] = 1; for (i = 2; i < n; i++) { ii[i] = savemod[ii[i-1]][a][0]; } jj[1] = 0; for (i = 2; i < n; i++) { jj[i] = savemod[jj[i-1]][a][1]; } for (b = 0; b < c; b++) for (x = 0; x < c; x++) if (amod[savemod[x][ii[n-1]][savemod[b][jj[n-1]][0]]][n-1] == fa[n-1] && amod[savemod[x][ii[2]][savemod[b][jj[2]][0]]][2] == fa[2]) { for (j = n-2; j>2 && amod[savemod[x][ii[j]][savemod[b][jj[j]][0]]][j] == fa[j]; --j); if (j == 2) { flag = true; ans[x][a][b] = true; } } } } if (flag == false) { cout << "Unsuccessful Hack Attempt" << endl; } else { for (i = 0; i < c; i++) for (j = 0; j < c; j++) for (k = 0; k < c; k++) if (ans[i][j][k]) cout << i << " " << j << " " << k << endl; } return 0; }
这里参考了该题doc写的题解,题解的地址为https://vijos.org/p/1965/solution。如果单纯用doc的暴力方法是不能通过的(能通过第5个测试点,但是后面的测试点不能通过),我另外加了一个优化。
考虑到N比C大很多的情况,这个时候计算fa[i]时取余运算(%i),就不起作用了,可以简化为
fa[i+1] = (fa[i] * a + b) % c(这里i >= c)
在这里只和a和b有关,与x无关,因此可以先枚举a和b,然后检验a和b是否可行,如果可行就进行,接下来枚举x再校验数列i<=c的情况(此时后面不需要校验了)。
另外这个程序要仔细编写,做尽可能的预处理,下面的测试结果可以看到在第5个测试点是很惊险地通过了。
测试数据 #0: Accepted, time = 15 ms, mem = 315184 KiB, score = 5 测试数据 #1: Accepted, time = 0 ms, mem = 315180 KiB, score = 5 测试数据 #2: Accepted, time = 0 ms, mem = 315180 KiB, score = 5 测试数据 #3: Accepted, time = 0 ms, mem = 315184 KiB, score = 5 测试数据 #4: Accepted, time = 937 ms, mem = 315184 KiB, score = 5 测试数据 #5: Accepted, time = 0 ms, mem = 315184 KiB, score = 5 测试数据 #6: Accepted, time = 0 ms, mem = 315180 KiB, score = 5 测试数据 #7: Accepted, time = 0 ms, mem = 315180 KiB, score = 5 测试数据 #8: Accepted, time = 15 ms, mem = 315188 KiB, score = 5 测试数据 #9: Accepted, time = 0 ms, mem = 315180 KiB, score = 5 测试数据 #10: Accepted, time = 78 ms, mem = 315184 KiB, score = 5 测试数据 #11: Accepted, time = 93 ms, mem = 315184 KiB, score = 5 测试数据 #12: Accepted, time = 93 ms, mem = 315184 KiB, score = 5 测试数据 #13: Accepted, time = 78 ms, mem = 315184 KiB, score = 5 测试数据 #14: Accepted, time = 93 ms, mem = 315180 KiB, score = 5 测试数据 #15: Accepted, time = 390 ms, mem = 315180 KiB, score = 5 测试数据 #16: Accepted, time = 296 ms, mem = 315180 KiB, score = 5 测试数据 #17: Accepted, time = 375 ms, mem = 315180 KiB, score = 5 测试数据 #18: Accepted, time = 437 ms, mem = 315184 KiB, score = 5 测试数据 #19: Accepted, time = 359 ms, mem = 315184 KiB, score = 5 Accepted, time = 3259 ms, mem = 315188 KiB, score = 100
相关文章推荐
- GCC 编译详解
- Java高级5
- java核心技术卷一第一天
- OGNL报错:Exception in thread "main" java.lang.ExceptionInInitializerError
- unix time stamp(时间戳)和常规时间相互转换的C++代码
- .net面试题目
- 编程实现函数int GetBitCount(short nn)
- 高效能人士的七个习惯
- 中国大学MOOC-陈越、何钦铭-数据结构 是否同一棵二叉搜索树
- Mac OS常用快捷键及常用功能
- mdpi、hdpi、xdpi、xxdpi对应的密度
- 细说高级程序员的几个成长阶段
- jQuery学习(一)
- (转帖)关于easyui中的datagrid在加载数据时候报错:无法获取属性"Length"的值,对象为null或未定义
- pascal语言中学版整理
- EOFError:EOF when reading a line
- 华为2013年机试题
- 本地主机ping上虚拟机的设置--hostonly方式
- Java 类加载与初始化
- 排序矩阵(杨氏矩阵)中的从小到大第k个数(C++)