【NOIP 2004】虫食算
因为一天机房都是断网状态,校内的小V评测这道题总显示Unaccept,所以下午放学后就和xiaoyimi晚上回家自习,来做一做这道题。
搜索+剪枝优化:
一开始我是顺着低位向高位填数,这么暴力在Vijos上有90分,如果NOIP能得这么多分我也甘心就写这个暴力吧
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int s1[27], s2[27], an[27], ans[27], n;
bool vis[27], pd = 0;
inline void dfs1(int, int);
inline void dfs3(int tmp, int delta) {
int c = an[tmp];
if (ans[c] == -1) {
int num = (ans[s1[tmp]] + ans[s2[tmp]] + delta), mo = num % n;
if (!vis[mo]) {
vis[mo] = 1;
ans[c] = mo;
dfs1(tmp + 1, num / n);
if (pd) return;
vis[mo] = 0;
ans[c] = -1;
}
} else {
int num = (ans[s1[tmp]] + ans[s2[tmp]] + delta);
if (ans[c] == num % n)
dfs1(tmp + 1, num / n);
if (pd) return;;
}
}
inline void dfs2(int tmp, int delta) {
int c = s2[tmp];
if (ans[c] == -1) {
for(int i = 0; i < n; ++i)
if (!vis[i]) {
vis[i] = 1;
ans[c] = i;
dfs3(tmp, delta);
if (pd) return;
vis[i] = 0;
ans[c] = -1;
}
} else {
dfs3(tmp, delta);
if (pd) return;
}
}
inline void dfs1(int tmp, int delta) {
if (tmp > n){
if (delta == 0)
pd = 1;
return;
}
int c = s1[tmp];
if (ans[c] == -1) {
for(int i = 0; i < n; ++i)
if (!vis[i]) {
vis[i] = 1;
ans[c] = i;
dfs2(tmp, delta);
if (pd) return;
vis[i] = 0;
ans[c] = -1;
}
} else {
dfs2(tmp, delta);
if (pd) return;
}
}
int main() {
scanf("%d\n", &n);
char c;
for(int i = n; i > 0; --i) {
c = getchar();
s1[i] = c - 'A';
}
scanf("\n");
for(int i = n; i > 0; --i) {
c = getchar();
s2[i] = c - 'A';
}
scanf("\n");
for(int i = n; i > 0; --i) {
c = getchar();
an[i] = c - 'A';
}
for(int i = 0; i < n; ++i)
ans[i] = -1;
dfs1(1, 0);
for(int i = 0; i < n; ++i)
printf("%d ",ans[i]);
return 0;
}
正解:先扫出字母出现的先后顺序,在这个扫出的序列上暴力,每次暴力后简单的扫一遍整个等式进行$check$,这是我写的唯一的也是最重要的剪枝,能过掉那组T掉的数据:
输入
20
NLHFIEASBRQJOGKMDPCT
NQGPSIIGKDMFDCBFMQSO
PNKNTOLHEIJHFGJKHJGG
输出
18 14 0 9 15 17 7 13 12 16 1 10 4 2 8 5 11 3 6 19
AC代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int s1[27], s2[27], an[27], ans[27], n, tb[27], tn = 0;
bool vis[27], pan = 0;
inline void mktb(int x) {
if (!vis[x]){
vis[x] = 1;
tb[++tn] = x;
}
}
inline bool pd() {
bool p = 0;
int delta = 0;
for(int i = 1; i <= n; ++i){
int a = ans[s1[i]], b = ans[s2[i]], c = ans[an[i]];
if (a == -1 || b == -1) {
p = 1;
} else {
if (c == -1) {
if (p) {
if (a + b == n-1)
p = 1;
else
p = 0, delta = (a + b) / n;
} else {
p = 0;
delta = (a + b + delta) /n;
}
} else {
if (p) {
if ((a + b) % n == c) {
p = 0;
delta = (a + b) / n;
} else if ((a + b + 1) % n == c) {
p = 0;
delta = (a + b + 1) / n;
} else
return 1;
} else {
if ((a + b + delta) % n != c)
return 1;
else {
p = 0;
delta = (a + b + delta) / n;
}
}
}
}
}
if (!p && delta == 1)
return 1;
else
return 0;
}
inline void dfs(int tmp) {
if (pd())
return;
if (tmp > n) {
pan = 1;
return;
}
for(int i = 0; i < n; ++i)
if (!vis[i]) {
vis[i] = 1;
ans[tb[tmp]] = i;
dfs(tmp + 1);
if (pan)
return;
vis[i] = 0;
ans[tb[tmp]] = -1;
}
}
int main() {
scanf("%d\n", &n);
char c;
for(int i = n; i > 0; --i) {
c = getchar();
s1[i] = c - 'A';
}
scanf("\n");
for(int i = n; i > 0; --i) {
c = getchar();
s2[i] = c - 'A';
}
scanf("\n");
for(int i = n; i > 0; --i) {
c = getchar();
an[i] = c - 'A';
}
for(int i = 1; i <= n; ++i) {
mktb(s1[i]);
mktb(s2[i]);
mktb(an[i]);
}
for(int i = 0; i < n; ++i)
vis[i] = 0, ans[i] = -1;
dfs(1);
for(int i = 0; i < n; ++i)
printf("%d ",ans[i]);
return 0;
}
没了,,,xyx和我玩了一下午的棋盘类游戏,SG什么的真的不会啊,省选要爆0了TwT
【NOIP 2004】虫食算的更多相关文章
- NOIP 2004 虫食算题解
问题 E: [Noip2004]虫食算 时间限制: 1 Sec 内存限制: 128 MB 题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一 ...
- Codevs 1064 虫食算 2004年NOIP全国联赛提高组
1064 虫食算 2004年NOIP全国联赛提高组 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 所谓虫食算,就是原先的算式 ...
- 虫食算 2004年NOIP全国联赛提高组(dfs)
1064 虫食算 2004年NOIP全国联赛提高组 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Descrip ...
- 深度优先搜索 codevs 1064 虫食算
codevs 1064 虫食算 2004年NOIP全国联赛提高组 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 所 ...
- 洛谷 P1092 虫食算 Label:dfs
题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 +8468#6633 44445509678 其中# ...
- codevs1064 虫食算
题目描述 Description 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 + 8468#6 ...
- NOIP2004 虫食算
描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子:43#9865#045+ 8468#6633= 44445506678其中#号代表 ...
- Luogu P1092 虫食算
题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 +8468#6633 44445509678 其中# ...
- 【NOIP2004】【CJOJ1703】【洛谷1092】虫食算
题面 题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 +8468#6633 44445509678 ...
- 【NOIP2004】虫食算
Description 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 +. 8468#6633 444455 ...
随机推荐
- 怎样运用好ZBrush中的布尔运算
我们知道DynaMesh常用于基础模型的起稿到中模的制作,它是ZBrush ® 4R2新增的功能,其强大的功能除了对模型进行重新布线,还可以进行布尔运算.配合Insert笔刷进行布尔运算,可以做出Z ...
- Codeforces 410C.Team[构造]
C. Team time limit per test 1 second memory limit per test 256 megabytes input standard input output ...
- Sass关于颜色函数的乐趣
阅读目录 1. 了解RGB和HSL颜色标准 2. RGB函数 3. HSL函数 4. Opacity函数 5. 其他颜色函数 6. 一个简单的应用 在Sass中,定义了很多现成的函数,可供我们使用.在 ...
- Vector3 *2 ,ToString()自动四舍五入
还以为出错了,仔细看发现ToString()自动四舍五入 Vector3 forward = Camera.main.transform.forward; Debug.Log("forwar ...
- maven-安装配置
Maven是基于项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具. maven是什么maven这个词可以翻译为“知识的积累”,也可以翻译为“专家”或“内行” ...
- C++ ODB 框架(未实践使用)
http://www.codesynthesis.com/products/odb/doc/manual.xhtml#17.1
- svn恢复被删除的分支 svn del 分支
笔者不小心,在操作时,删除了一个主开发分支(main_dev). 一. 悲剧的语句: svn del -m"1.误删除分支" http://svr_path/branches/ ...
- offsetParent详解
offsetParent与parentNode一样,都是获取父节点,但是offsetParent却有很大的不同之处: offsetParent找有定位的父节点,没有定位默认是body,ie7以下定位在 ...
- Linux中 groupadd 和 useradd 的命令说明
groupadd [options] group 说明The groupadd command creates a new group account using the values specifi ...
- git工作区、暂存区、版本库之间的关系
区分三者关系 Git最让你迷惑的无非是它里面的各种概念了,如果是刚开始接触Git希望看完本篇介绍之后有一个清晰的认识,笔者认识也有限这里只说说个人对使用Git的感受,说一下它里面的几个最常用的概念的理 ...