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/ ...
随机推荐
- *HDU1151 二分图
Air Raid Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
- ZK textbox Constraint验证
test.zul: <?page title="" contentType="text/html;charset=UTF-8"?> <zk x ...
- InnoDB与Myisam的六大区别
MyISAM InnoDB 构成上的区别: 每个MyISAM在磁盘上存储成三个文件.第一个文件的名字以表的名字开始,扩展名指出文件类型. .frm文件存储表定义. 数据文件的扩展名为. ...
- C++ 用RGB 三种颜色绘图
#include <iostream> #include <cmath> #include <cstdlib> #define DIM 1024 #define D ...
- Flink – window operator
参考, http://wuchong.me/blog/2016/05/25/flink-internals-window-mechanism/ http://wuchong.me/blog/201 ...
- redis3.2新增属性protected mode
在安装新版redis时(3.2) , 一直出现问题 , 只能本机连接其他机器访问失败 , 后来发现是新版增加了安全机制 在配置文件里可以发现多出了protected-mode这一项 , 如果为yes ...
- [flex布局]-flex教程
简介:2009年,W3C提出了一种新的方案----Flex布局,可以简便.完整.响应式地实现各种页面布局.目前,它已经得到了所有浏览器的支持,这意味着,现在就能很安全地使用这项功能. Flex布局是什 ...
- iOS 简单滤镜
转自:http://blog.csdn.net/lovechris00/article/details/51496458 1.主要是运用 ImageUtil库,把原图通过矩阵色值设置层不同滤镜效果下的 ...
- setTimeout调用带参数的函数的方法
function test(s){ alert(s);}window.setTimeout(function(){test('str');},1000);这样就可以了...为什么是这样呢.因为s ...
- JavaScript:异步 setTimeout
setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式. function showDate(){ var date=new Date(); console.log(date); } ...