您的位置:首页 > 其它

NYOJ 929 密码宝盒 || HDU 1226 超级密码

2013-11-24 12:28 435 查看
题目链接~~>

做题感悟:

              开始听了学长讲课后在杭电上做过这个题,之后又在比赛时遇见,当时有点不淡定 RE 了三次,开始以为数组开小了后来才发现没有考虑到 n = 0 ;的情况,以后即使遇到原题也应该认真读题。

题意:

         给你一个 n ,m个C进制的数。让你组合成最小的数字是 n 的倍数。

解题思路:

               这需要数学知识,r = k ( mod n ) 则 ( k * p + a ) ( mod c ) = ( r * p + a ) ( mod  n ) ;余数出现过如果再次出现就不用再次使用。

代码(本人):

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std ;
int n,m,c ;
int g[20] ;
bool vis[10000] ;
struct zhang
{
int x,y[505],num,bu ;
} ;
bool bfs()
{
int i,j ;
queue<zhang>q ;
zhang cur,next ;
memset(vis,false,sizeof(vis)) ;
cur.x=0 ;
cur.num=0 ;
cur.bu=0 ;
q.push(cur) ;
while(!q.empty())
{
cur=q.front() ;
q.pop() ;
for(i=0 ;i<n ;i++)
{
next.x=cur.x*c+g[i] ;
if(!next.x) continue ; // 前缀不能是 0
next.bu=cur.bu+1 ;
next.num=cur.num+1 ;
next.x=next.x%m ;
if(vis[next.x]||next.num>500) continue ; // 如果余数出现过或长度大于 500 不继续下去
vis[next.x]=1 ;
for(j=0 ;j<cur.num ;j++)
next.y[j]=cur.y[j] ;
next.y[cur.num]=g[i] ;
if(!next.x) // 找到解输出
{
for(j=0 ;j<next.num ;j++)
if(next.y[j]>9)
printf("%c",next.y[j]+55) ;
else        printf("%d",next.y[j]) ;
printf("\n") ;
return true ;
}
q.push(next) ;
}
}
return false ;
}
int main()
{
int T,i ;
char ch ;
scanf("%d",&T) ;
while(T--)
{
scanf("%d%d%d",&m,&c,&n) ;
for(i=0 ;i<n ;i++)
{
getchar() ;
scanf("%c",&ch) ;
if(ch>='A'&&ch<='F')
g[i]=ch-55 ;
else    g[i]=ch-'0' ;
}
sort(g,g+n) ; // 排序让第一个找到的是最小的
if(!m) // 0 需要特判一下
{
if(!g[0])
printf("0\n") ;
else
printf("give me the bomb please\n") ;
continue ;
}
if(!bfs())
printf("give me the bomb please\n") ;
}
return 0 ;
}

代码:

#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
#include<iostream>
#define MX 50005
using namespace std ;
int n,c,m ;
int g[18] ;
bool vis[MX] ;
struct zhang
{
int x,m,pre,cnt ;
}q[MX] ;
void gettep(int k)
{
if(k==-1)
return ;
gettep(q[k].pre) ;
if(q[k].x>=10)
printf("%c",q[k].x+55) ;
else    printf("%c",q[k].x+'0') ;
return ;
}
int bfs()
{
int head=0,tail=-1 ;
memset(vis,false,sizeof(vis)) ;
for(int i=0 ;i<m ;i++)
{
if(!g[i]) continue ;
zhang next ;
next.pre=-1 ;
next.x=g[i] ;
next.m=g[i]%n ;
vis[next.m]=true ;
next.cnt=1 ;
q[++tail]=next ;
}
while(head<=tail)
{
int h=head ;head++ ;
if(q[h].cnt>500) continue  ;
if(!q[h].m)
{
gettep(h) ;
return true  ;
}
for(int i=0 ;i<m ;i++)
{
int key=(q[h].m*c+g[i])%n ;
if(vis[key]) continue ;
vis[key]=true ;
zhang tep ;
tep.m=key ;   tep.x=g[i] ;
tep.pre=h ;   tep.cnt=q[h].cnt+1 ;
q[++tail]=tep ;
}
}
return false ;
}
int main()
{
int T,i ;
char ch ;
scanf("%d",&T) ;
while(T--)
{
scanf("%d%d%d",&n,&c,&m) ;
for(i=0 ;i<m ;i++)
{
cin>>ch ;
if(ch>='A'&&ch<='F')
g[i]=ch-55 ;
else   g[i]=ch-'0' ;
}
sort(g,g+m) ;
if(!n)
{
if(!g[0]) printf("0") ;
else      printf("So Sorry.") ;
puts("") ;
continue ;
}
if(!bfs())
printf("So Sorry.") ;
puts("") ;
}
return 0 ;
}

优代码:

#include <queue>
#include <string>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int N = 5005;
bool vis
;
string ans;
int a[17],pre
,ansAt
,n,m,c;
int ctoi(char c)
{
return c >= '0' && c <= '9' ? c - '0' : c - 'A' + 10;
}
char itoc(int i)
{
return i <= 9 ? i + '0' : i + 'A' - 10;
}
bool bfs()
{
queue<int> q;
q.push(0);
while(!q.empty())
{
int cur = q.front();q.pop();
for(int i=0;i<m;i++)
{
int nxt = (cur * c + a[i]) % n;
if(cur == 0 && a[i] == 0 || vis[nxt])
continue;
vis[nxt] = true;
ansAt[nxt] = a[i];
pre[nxt] = cur;
if(nxt == 0)
return true;
q.push(nxt);
}
}
return false;
}

bool check()
{
ans = "";
int p = 0;
do
{
ans += itoc(ansAt[p]);
p = pre[p];
}while(p);
return (int)ans.size() <= 500;
}

int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(vis,false,sizeof(vis));
scanf("%d%d%d",&n,&c,&m);
for(int i=0;i<m;i++)
{
char num[3];
scanf("%s",num);
a[i] = ctoi(num[0]);
}
sort(a,a+m);
if(n == 0)
{
puts(a[0] == 0 ? "0" : "So Sorry.");
continue;
}
if(bfs() && check())
{
for(int i=(int)ans.size()-1;i>=0;i--)
putchar(ans[i]);
puts("");
}
else
puts("So Sorry.");
}
return 0;
}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: