1016. Boundaries on A New Kind of Science 解题报告
题目链接:
http://soj.sysu.edu.cn/1016
题目大意:
给定一个字符串和256条规则,将某条规则应用于字符串,字符串将发生变化,给定一个数max,求出在max步内可以将字符串变为指定字符串的规则号以及步数。
题目分析:
既然只有256条规则,而且步数又有限制,那我们就暴力模拟,把所有情况都求出来就行了,但是如果用原始字符串来做是非常慢的,虽然题目的时间限制很宽松(10s),但也是会超时的。所以对于每个规则我用一个record的map来保存已经遇到过的字符串,这样就可以过了(虽然还是很慢)。
在网上看到的做法是用0,1分别代表白黑的,而且用到了很多位运算,虽然也是暴力,但是快很多,一样的测试,人家0.15s就过了。
代码:
- // Problem#: 1016
- // Submission#: 3585804
- // The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
- // URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
- // All Copyright reserved by Informatic Lab of Sun Yat-sen University
- #include <stdio.h>
- #include <string.h>
- //
- int rule[][], m[];
- long long step, length;
- char num[], target[];
- int targetNum[], pro[][];
- int answerNum, ans1[], ans2[];
- int MAX() {
- if (length < ) return m[length];
- else return ;
- }
- void init() {
- for (int i = ; i < ; i++) {
- int temp = i;
- for (int j = ; j < ; j++) {
- rule[i][j] = temp & ;
- temp >>= ;
- }
- }
- m[] = ;
- for (int i = ; i < ; i++) m[i] = m[i - ] << ;
- }
- bool check() {
- length = strlen(target);
- if (length < ) return false;
- for (int i = ; i < length; i++) {
- if (target[i] == 'W') targetNum[i] = ;
- else if (target[i] == 'B') targetNum[i] = ;
- else return false;
- }
- if ((targetNum[] == ) || (targetNum[length - ] == ) || (length & == )) return false;
- return true;
- }
- int main() {
- init();
- int caseNum = ;
- while () {
- scanf("%s%s", num, target);
- if (strcmp(num, "END") == ) break;
- printf("LINE %d ", caseNum++);
- if (!check()) {
- printf("NONE\n");
- continue;
- }
- step = ;
- for (int i = ; num[i] != '\0'; i++) step = step * + num[i] - '';
- if (step > MAX()) step = MAX();
- answerNum = ;
- for (int i = ; i < ; i++) {
- memset(pro, , sizeof(pro));
- int last = , now = ;
- int s = ;
- int jlength = length - , ruleNum;
- pro[now][length / ] = ;
- while () {
- if (s > step) break;
- bool isSame = true;
- for (int k = ; k < length; k++) {
- if (pro[now][k] != targetNum[k]) {
- isSame = false;
- break;
- }
- }
- if (isSame) {
- ans1[answerNum] = i;
- ans2[answerNum] = s;
- answerNum++;
- break;
- }
- now ^= ;
- last ^= ;
- s++;
- for (int j = ; j < jlength; j++) {
- ruleNum = pro[last][j];
- ruleNum <<= ;
- ruleNum += pro[last][j + ];
- ruleNum <<= ;
- ruleNum += pro[last][j + ];
- pro[now][j + ] = rule[i][ruleNum];
- }
- pro[now][] = pro[now][length - ] = ;
- }
- }
- if (answerNum) {
- for (int i = ; i < answerNum; i++) printf("(%d,%d)", ans1[i], ans2[i]);
- printf("\n");
- } else printf("NONE\n");
- }
- return ;
- }
这提示我以后能用int尽量不用字符串。多考虑效率。这道题要是时间限制到1s我就GG了。
我的代码:
- #include <iostream>
- #include <map>
- #include <vector>
- #include <string.h>
- using namespace std;
- struct Ans {
- int mo, t;
- Ans(){}
- Ans(int a, int b) {
- mo = a;
- t = b;
- }
- };
- //0 for white, 1 for black
- int model[];
- map<string, int> transfer;
- map<string, int> record;
- vector<Ans> ans;
- int Max;
- string line;
- string ary, dest, ary2;
- int l;
- void addModel() {
- int i = , j;
- while (i >= && model[i]) {
- i--;
- }
- for (j = i; j <= ; j++) {
- model[j] = -model[j];
- }
- }
- int toInt(string tmp) {
- int i, tot = ;
- for (i = ; i < tmp.length(); i++) {
- tot = tot* + tmp[i] - '';
- }
- return tot;
- }
- void getData(int& n, string& r) {
- string tmp1, tmp2;
- tmp1 = tmp2 = "";
- int i;
- for (i = ; r[i] != ' '; i++) {
- tmp1 += r[i];
- }
- for (i++; i<r.length(); i++) {
- tmp2 += r[i];
- }
- n = toInt(tmp1);
- dest = tmp2;
- l = dest.length();
- }
- bool cut(int f) {
- string tmp;
- int i;
- for (i = ; i < ; i++) {
- tmp += ary2[f+i];
- }
- return model[transfer[tmp]];
- }
- void Do() {
- int i;
- ary2 = ary;
- for (i = ; i < l-; i++) {
- if (cut(i)) {
- ary[i+] = 'B';
- } else {
- ary[i+] = 'W';
- }
- }
- }
- bool equal(const string& a, const string& b) {
- int i;
- for (i = ; i < l; i++) {
- if (a[i] != b[i]) {
- return false;
- }
- }
- return true;
- }
- int main() {
- transfer["BBB"] = ;
- transfer["BBW"] = ;
- transfer["BWB"] = ;
- transfer["BWW"] = ;
- transfer["WBB"] = ;
- transfer["WBW"] = ;
- transfer["WWB"] = ;
- transfer["WWW"] = ;
- int cnt = ;
- while (getline(cin, line)) {
- cnt++;
- if (line == "END OF INPUT")
- break;
- ans.clear();
- getData(Max, line);
- int i, j, k;
- for (i = ; i < ; i++) {
- ary = "";
- for (k = ; k < l; k++) {
- ary += 'W';
- }
- ary[l/] = 'B';
- record.clear();
- for (j = ; j < Max; j++) {
- if (record[ary]) {
- break;
- }
- if (equal(ary, dest)) {
- ans.push_back(Ans(i, j+));
- break;
- } else {
- record[ary] = ;
- }
- Do();
- }
- addModel();
- }
- cout << "LINE " << cnt << " ";
- for (i = ; i < ans.size(); i++) {
- cout << "(" << ans[i].mo << "," << ans[i].t << ")";
- }
- if (!ans.size()) {
- cout << "NONE";
- }
- cout << endl;
- }
- }
1016. Boundaries on A New Kind of Science 解题报告的更多相关文章
- HOJ题目分类
各种杂题,水题,模拟,包括简单数论. 1001 A+B 1002 A+B+C 1009 Fat Cat 1010 The Angle 1011 Unix ls 1012 Decoding Task 1 ...
- 转载 ACM训练计划
leetcode代码 利用堆栈:http://oj.leetcode.com/problems/evaluate-reverse-polish-notation/http://oj.leetcode. ...
- (转)POJ题目分类
初期:一.基本算法: (1)枚举. (poj1753,poj2965) (2)贪心(poj1328,poj2109,poj2586) (3)递归和分治法. (4)递推. ...
- poj分类
初期: 一.基本算法: (1)枚举. (poj1753,poj2965) (2)贪心(poj1328,poj2109,poj2586) (3)递归和分治法. ( ...
- POJ1325 Machine Schedule
Description As we all know, machine scheduling is a very classical problem in computer science and h ...
- POJ题目分类(按初级\中级\高级等分类,有助于大家根据个人情况学习)
本文来自:http://www.cppblog.com/snowshine09/archive/2011/08/02/152272.spx 多版本的POJ分类 流传最广的一种分类: 初期: 一.基本算 ...
- POJ题目分类(转)
初期:一.基本算法: (1)枚举. (poj1753,poj2965) (2)贪心(poj1328,poj2109,poj2586) (3)递归和分治法. (4)递推. ...
- ACM学习
转:ACM大量习题题库 ACM大量习题题库 现在网上有许多题库,大多是可以在线评测,所以叫做Online Judge.除了USACO是为IOI准备外,其余几乎全部是大学的ACM竞赛题库. US ...
- POJ3974 Palindrome
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
随机推荐
- 【Alpha】Daily Scrum Meeting第三次
本次随笔调换了展示顺序,把重要的内容放前面. 一.本次Daily Scrum Meeting主要内容 说明要完成alpha版本还需要哪些功能 对这些功能进行分析和实现方式的讨论 强调编码规范和变量命名 ...
- ImportError: The _imagingft C module is not installed
添加验证码模块的时候,发布到服务器上居然报了这个错误 ImportError: The _imagingft C module is not installed 然而pillow是已经装在服务器上的, ...
- 使用Hibernate SQLQuery(转)
原文地址:http://itindex.net/detail/51776-hibernate-sqlquery-sql,重新排了一下版 Hibernate对原生SQL查询的支持和控制是通过SQLQue ...
- java常用集合框架底层实现简介与注意点
Collection: ArrayList:1:底层实现是数组,默认长度是10.2:add(),判断是否数组越界,是数组扩容为原来的两倍.3:remove(),copy数组,size-1,释放空虚的空 ...
- BAT常用脚本汇总
1.取得时间戳 @echo off set date0=%date:~0,10% set hour0=%time:~0,2% set time0=%time:~0,2%%time:~3,2%%time ...
- h5的离线缓存机制
什么是Manifest: 其实Manifest是一个简单的 文本文件,它的扩展名是任意的,定义需要缓存的文件.资源,当第一次打开时,浏览器会自动缓存相应的资源. Manifest 的特点: 离线浏览: ...
- php面试题
1.用PHP打印出前一天的时间格式是2006-5-10 22:21:21(2分) <?php date_default_timezone_set('Asia/shanghai'); echo d ...
- phyton 相关学习
http://www.nowamagic.net/academy/category/13/ http://www.runoob.com/python/python-reg-expressions.ht ...
- springmvc 动态代理 JDK实现与模拟JDK纯手写实现。
首先明白 动态代理和静态代理的区别: 静态代理:①持有被代理类的引用 ② 代理类一开始就被加载到内存中了(非常重要) 动态代理:JDK中的动态代理中的代理类是动态生成的.并且生成的动态代理类为$Pr ...
- Python开发【前端】:汇总
页面模板 1.EasyUI(推荐指数★) JQuery EasyUI中文网 下载 使用方法:把文件下载到本地.直接从官网上把源码拷贝过来,更改下js的路径即可 优点:功能非常多.非常齐全 偏做后台管理 ...