[考试]20150815
1、前言
水考一次。。。。主题是搜索,去年11月考过一次,当时只有200多分。这也算是最近考试中极其简单的一次了吧,只需要在搜索上稍加技巧即可。
2、Queen N皇后问题
大概题意:这么经典的题就不用讲题目了吧。
题解:直接DFS,注意需要输出方案。
代码:
-------------------------------------------------------------------------------------------------------
#include<cstdio>
int n,h[100],g[100],l[100],a[100],flag;
void print()
{
for (int i=1;i<=n;i++) printf("%d ",a[i]);
printf ("\n");
}
void DFS(int k)
{
for (int i=1;i<=n;i++)
{
if (!h[i] && !g[i+k] && !l[i-k+n])
{
h[i]=g[i+k]=l[i-k+n]=1;
a[k]=i;
if (k==n) flag=1,print(); else DFS(k+1);
h[i]=g[i+k]=l[i-k+n]=0;
}
}
}
int main()
{
freopen("queen.in","r",stdin);
freopen("queen.out","w",stdout);
scanf("%d",&n);
DFS(1);
if (!flag) printf ("-1");
return 0;
}
-------------------------------------------------------------------------------------------------------
3、Grz 爬山
大概题意:给出一个n*n矩阵,请找出满足两种条件中一种的格子集合的个数。条件一:所有格子权值相同,都八方联通,且外围所有格子权值大于格子集合;条件二:所有格子权值相同,都八方联通,且外围所有格子权值小于格子集合。
总结:当时这道题其实是写出来了的,但是在define方面出现了当时并不清楚的错误,导致数组开小。
题解:这道题同样直接BFS即可,稍微注意一下边界的判断方式,直接取-INF或INF都是不可取的。
代码略。
4、Quantum 变换
大概题意:http://www.cnblogs.com/jinkun113/p/4714076.html 中的第四题。唯一变化在于权值均为1。
总结:做过的题目了,第一次直接NP滚粗;第二次做也就是8月8号,因为对位运算符的不熟悉,导致常数50被卡。现在当然还是AC了。
题解:见大概题意中的链接。
代码:
-------------------------------------------------------------------------------------------------------
#include<cstdio>
#include<cstring>
#define MAXN 21
#define INF 0x3f3f3f3f
int len,m,n,q[1<<MAXN],f[1<<MAXN],s,t,a[MAXN*3],b[MAXN*3],c[MAXN*3];
char ch[MAXN],t1[MAXN],t2[MAXN];
void init()
{
freopen("quantum.in","r",stdin);
freopen("quantum.out","w",stdout);
scanf("%d %d %d",&len,&m,&n);
for (int i=1;i<=m;i++)
{
scanf("%s",ch);
for (int j=0;j<=len-1;j++)
{
if (ch[j]!='C') a[i]+=1<<j;
if (ch[j]=='S') b[i]+=1<<j;
if (ch[j]=='F') c[i]+=1<<j;
}
}
}
int work()
{
int head=1,tail=2;
memset(f,INF,sizeof(f)),memset(q,0,sizeof(q));
q[1]=s,f[s]=0;
while (head!=tail)
{
for (int i=1;i<=m;i++)
{
int temp=((q[head]&a[i])|b[i])^c[i];
if (f[q[head]]+1<f[temp]) f[temp]=f[q[head]]+1,q[tail]=temp,tail++;
}
head++;
}
return (f[t]==INF)?-1:f[t];
}
int main()
{
init();
for (int i=1;i<=n;i++)
{
s=t=0;
scanf("%s %s",t1,t2);
for (int i=0;i<=len-1;i++) s+=(t1[i]-'0')<<i,t+=(t2[i]-'0')<<i;
int ret=work();
if (ret==-1) printf("NP\n"); else printf("%d\n",ret);
}
return 0;
}
-------------------------------------------------------------------------------------------------------
5、Ant 反质数
大概题意:定义g(x)表示x的约数个数,定义x为反质数当且仅当g(x)>g(i)(i∈[1,x]),求出不超过n的最大反质数。
题解:我印象中江哥好像出过一个数据范围比这个大多了的丧病题目?但是此时此刻n<=10^14,所以我们丝毫不虚地打个质数表然后暴力DFS找就是了。。。
代码:
-------------------------------------------------------------------------------------------------------
#include<cstdio>
typedef long long ll;
int prime[14]={2,3,5,7,11,13,17,19,23,29,31,37,41,43};
ll maxn,ans,n;
void DFS(ll num,int k,ll sum,int t)
{
ll temp;
if (sum>maxn) maxn=sum,ans=num;
if (sum==maxn && ans>num) ans=num;
if (k>=14) return;
temp=num;
for (int i=1;i<=t;i++)
{
if (temp*prime[k]>n) break;
temp*=prime[k];
DFS(temp,k+1,sum*(i+1),i);
}
}
int main()
{
freopen("ant.in","r",stdin);
freopen("ant.out","w",stdout);
scanf("%I64d",&n);
DFS(1,0,1,50);
printf("%I64d",ans);
return 0;
}
-------------------------------------------------------------------------------------------------------