您的位置:首页 > 大数据 > 人工智能

hihocoder 1251 Today Is a Rainy Day (2015ICPC北京C题)

2016-11-08 15:37 411 查看
题目链接:http://hihocoder.com/problemset/problem/1251

转载声明:http://blog.csdn.net/lyc1635566ty/article/details/53074067

题意:

给你2个数字串,每个数字串的数字只会有{1,2,3,4,5,6},6个数字组成,然后给你2个操作

1)将一个数字变成另外的数字.

2 ) 讲一类相同的数字变成另外的数字.

问最少次数可以变成目的串..

分析:

今天补了一下2015北京赛题.

这简直烧智商啊,我开始感觉就是bfs,我也没往其他方向去想,可是我根本不会做.最主要难处理的是那个一堆变的状态,我想到的状态转换要用 110^36 的空间 来保留我走过的位置,我记得我们也做过一个类似的bfs 就是那个 素数路径到另一个目的数字的状态,我总想着这是一个模型,一直往那个地方想,可是我的状态好难定啊..然后果断godie,看看题解,这是个银牌题啊..真难..

这是我第一次搞的bfs,大神的思想就不一样,首先,我们想,明显先操作了操作2,再来用操作1的方式最好.可能有人觉得我可能先做操作1,然后我再来个操作2,再操作1.可是你仔细想想,要是这样的话状态更乱,而且之前转得可能也是白费的.

我是这样想的,既然认为先做操作1,再做操作2,

莫非就产生两种情况.

操作1把原来的数字改对了,然后你通过操作2填完整序列

例如 22222 21222

11111 11111 这时就血亏了.明明一次就行了

又或者说说,把他改错..

例如 21222 22222

11111 11111 这样子又明明可能多了一次,为什么? 如果他本身是错的,改过来还是错,那么这还是2次,如果他本身是对的,你却要硬生生改错,这就白白浪费一次.对吧?

反正牵一发而动全身的东西就应该先做,这道题目的转弯角度很大.转不过弯来GG,能转过弯来就不是问题了.还是能力问题啊.

反正原来的状态 他是1就是1 123456

然后从 123456 转化成 其他数字,

顶多就 6^6次种,然后我们就可以确定 原来有的数字怎么转了..

然后再暴力操作1即可得答案.

代码:

/* Author:GavinjouElephant
* Title:
* Number:
* main meanning:
*
*
*
*/

#include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <vector>
#include <set>
#include <cstdlib>
#include <map>
#include <queue>
//#include<initializer_list>
//#include <windows.h>
//#include <fstream>
//#include <conio.h>
#define MaxN 0x7fffffff
#define MinN -0x7fffffff
#define lson 2*k
#define rson 2*k+1
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=666666+10;;

int Scan()//读入整数外挂.
{
int res = 0, ch, flag = 0;

if((ch = getchar()) == '-')             //判断正负
flag = 1;

else if(ch >= '0' && ch <= '9')           //得到完整的数
res = ch - '0';
while((ch = getchar()) >= '0' && ch <= '9' )
res = res * 10 + ch - '0';
return flag ? -res : res;
}
void Out(int a)    //输出外挂
{
if(a>9)
Out(a/10);
putchar(a%10+'0');
}

int vis[maxn];
queue<int>gg;
int ansn[maxn];
int anst[maxn];
int num;
char s1[maxn];
char s2[maxn];

void init()
{
for(int i=1;i<maxn;i++){vis[i]=maxn;}
num=1;
ansn[1]=123456;
anst[1]=0;
gg.push(123456);
vis[123456]=0;

while(!gg.empty())
{
int t1=gg.front();
int p=t1;
gg.pop();
int b[10];
for(int j=6;j>=1;j--) {
b[j]=p%10;
p/=10;
}
for(int i=1;i<=6;i++) { //当前状态中的i变成j
for(int j=1;j<=6;j++) {
if(i==j) continue;
int tt=0;
for(int k=1;k<=6;k++) {
if(b[k]==i) {
tt=tt*10+j;
}
else {
tt=tt*10+b[k];
}
}
if(vis[t1]+1<vis[tt]) {
vis[tt]=vis[t1]+1;
gg.push(tt);
num++;
ansn[num]=tt;
anst[num]=vis[tt];
}

}
}
}
}
int main()
{
init();
while(scanf("%s%s",s2,s1)!=EOF)
{
int minx=maxn;
for(int i=1;i<=num;i++)
{
int tot=anst[i];
int a[10];
int p=ansn[i];
for(int j=6;j>=1;j--)
{
a[j]=p%10;
p/=10;
}

for(int i=0;s1[i]!='\0';i++)
{
if(s1[i]==1+'0')
{
if((a[1]+'0')!=s2[i])tot++;
continue;
}
if(s1[i]==2+'0')
{
if((a[2]+'0')!=s2[i])tot++;
continue;
}
if(s1[i]==3+'0')
{
if((a[3]+'0')!=s2[i])tot++;
continue;
}
if(s1[i]==4+'0')
{
if((a[4]+'0')!=s2[i])tot++;
continue;
}
if(s1[i]==5+'0')
{
if((a[5]+'0')!=s2[i])tot++;
continue;
}
if(s1[i]==6+'0')
{
if((a[6]+'0')!=s2[i])tot++;
continue;
}
}
minx=min(minx,tot);
}
printf("%d\n",minx);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: