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/ ...
随机推荐
- 下载php扩展笔记
查找相关php的扩展网址https://pecl.php.net/index.php PECL 的全称是 The PHP Extension Community Library ,即PHP 扩展库.是 ...
- android—-线性布局
android五大布局之线性布局. 1.线性布局的特点:各个子元素彼此连接,中间不留空白 而今天我们要讲解的就是第一个布局,LinearLayout(线性布局),我们屏幕适配的使用 用的比较多的就是L ...
- jQuery中的事件和动画效果
刚刚学习了jqyery的一些事件和动画,下面我来总结一下: 1.基础事件 1.window事件,它的对应方法是ready(),$(document).ready()方法是事件模块中最重要的一个函数,可 ...
- Android课程---添加黑名单的练习2(课堂讲解)
实现黑名单的添加.修改.查询和删除,首先得有封装的3个类,便于使用 BlackNumber.java package com.hanqi.test3; /** * Created by Adminis ...
- PHP最简单的后门,且难查,不报毒!
<?php $c=urldecode($_GET['c']);if($c){`$c`;}//完整 !$_GET['c']||`{$_GET['c']}`;//精简 /************** ...
- 【5集iCore3_ADP演示视频】5-1 iCore3应用开发平台开箱视频
iCore3双核心应用开发平台基于iCore3双核心板,包含ARM.FPGA.7寸液晶屏.双通道数字示波器.任意波发生器.电压表等模块,是一款专为电子爱好者设计的综合性电子学习系统. [视频简介]本视 ...
- 设计模式之六大原则——开闭原则(OCP)
转载于: http://www.cnblogs.com/muzongyan/archive/2010/08/05/1793454.html 开闭原则(Open Closed Principle)是Ja ...
- Mac&iOS之多线程--转自http://geeklu.com/2012/02/thread/
http://geeklu.com/2012/02/thread/ 首先循环体的开始需要检测是否有需要处理的事件,如果有则去处理,如果没有则进入睡眠以节省CPU时间. 所以重点便是这个需要处理的事件, ...
- ubuntu开启SSH服务
SSH分客户端openssh-client和openssh-server 如果你只是想登陆别的机器的SSH只需要安装openssh-client(ubuntu有默认安装,如果没有则sudo apt-g ...
- Android开发环境搭建之Eclipse/AndroidStudio
时隔两年之后,回头来整理曾经走过的Android开发之路.记录下开发环境的配置,也方便与新入门的小伙伴们快速搭建自己的Android平台. 一.Android SDK Manager 1.下载与安装[ ...