[考试]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;
}

-------------------------------------------------------------------------------------------------------

posted @ 2015-08-17 16:43  jinkun113  阅读(205)  评论(0编辑  收藏  举报