【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 ...
随机推荐
- ExecutorType 的类型
- ANE原生代码的调试(安卓)
忙了一天终于有空继续这篇教程了. ANE的原生代码的调试其实在Adobe的官网有介绍的,但是同样很含糊,我摸索了一段时间现在记录下我的心得. 首先你得安装Eclipse,然后你得启动Eclipse 然 ...
- 平滑过渡的战争迷雾(一) 原理:Warcraft3地形拼接算法
本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9611887 作者:七十一雾央 新浪微博:http:/ ...
- PhpExcel中文帮助手册|PhpExcel使用方法
下面是总结的几个使用方法 include 'PHPExcel.php'; include 'PHPExcel/Writer/Excel2007.php'; //或者include 'PHPExcel/ ...
- zlog学习笔记(zc_hashtable)
zc_hashtable.h /** * hashtable */ #ifndef __zc_hashtable_h #define __zc_hashtable_h typedef struct z ...
- switch2osm使用open street map离线地图中文乱码方框解决办法
----------written by shenwenkai------------- ubuntu linux环境下,按照网址(https://switch2osm.org/serving-til ...
- BZOJ 1016 【JSOI2008】 最小生成树计数
Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...
- jQuery EasyUI 1.3.4 API CHM版下载
网盘下载
- PRML读书会第十章 Approximate Inference(近似推断,变分推断,KL散度,平均场, Mean Field )
主讲人 戴玮 (新浪微博: @戴玮_CASIA) Wilbur_中博(1954123) 20:02:04 我们在前面看到,概率推断的核心任务就是计算某分布下的某个函数的期望.或者计算边缘概率分布.条件 ...
- 深入体验bash on windows,在windows上搭建原生的linux开发环境,酷!
今年微软Build 2016大会最让开发人员兴奋的消息之一,就是在Windows上可以原生运行Linux bash,对开发人员来说,这是一个喜闻乐见的消息. 1 安装 你必须安装开发者预览版本,才能使 ...