2012年"浪潮杯"山东省第三届ACM大学生程序设计竞赛(热身赛)

Super Prime

Time Limit: 1000MS Memory limit: 65536K

题目描述

We all know, prime is a kind of special number which has no other factors except of 1 and itself.
2,3,5,7,11,13,17,19,23,29 are the top 20 primes.
Now there is a new question about prime:
We call a prime as super prime when and only when which can be represented as the sum of multiple continuous primes. For example: 5=2+3, so 5 is a super prime.
Please program to judge whether a number is a super prime or not.

输入

The first line is an integer T (T<=1000), and then T lines follow.
There is only one positive integer 
N(1<N<100000) for each case.

输出

For each case you should output the case number first, and then the word "yes" if the integer N is a super prime, and you should output "no" otherwise.

示例输入

3
5
7
8

示例输出

Case 1: yes
Case 2: no
Case 3: no
算法很简单先筛法求素数,但是题目里的条件是要只有能用连续的素数表示才行所以单个的素数不行。
后来发现把最后的一个素数99991,只有一个但是刚好存素数的数组都赋初值为0,导致99991也变成
super prime了╮(╯▽╰)╭。其实最后一个不用枚举他一定不是super prime,因为super prime
至少要能用2个连续的素数表示
#include <stdio.h>
#define max 100000
long a[1000001],b[100001],c[10000];
void main ()
{long i,j,k,t,n,ii;
 for (i=0;i<=100000;i++)
 {a[i]=1;b[i]=0;}
 a[0]=0;a[1]=0;
 k=2;
 while (k<=max)
 {t=k;
  while (t<=max)
  {t=t+k;
  if (t<=max) a[t]=0;
  }
  ++k;
  while ((a[k]==0)&&(k<=max)) ++k;
 }
 k=0;
 for (i=1;i<=max;i++)
  if (a[i]) {++k;c[k]=i;}
 for (i=1;i<k;i++)
 {t=c[i];j=i;
  while (t<=max)
  {++j;
   t=t+c[j];
   if ((t<=max)&&(a[t])&&(b[t]==0)) b[t]=1;
  }
 }
 scanf("%d",&t);
 for (i=1;i<=t;i++)
 {scanf("%d",&n);
  printf("Case %d: ",i);
  if (b[n]) printf("yes\n");
  else printf("no\n");
 }
}
Sdut2045

Strange Square

Time Limit: 1000MS Memory limit: 65536K

题目描述

Small Jan and Rain are playing an interesting game: Strange Square. A stranger square is a square of numbers that is arranged such that every row and column has the same sum. For example:
1 2 3
3 2 1
2 2 2
Now, there are 9 numbers (-100000 <= xi <= 100000) and they want to know the number of distinct ways those numbers can be arranged in a strange square. Two squares are distinct if they differ in value at one or more positions.

输入

The input contains multiple test cases. The first line is the number of cases T (0 < T <= 100).
Each case contains a line with 9 numbers.

输出

You should output one line for each test case. The line contains the case number first, and then one integer indicating the number of distinct ways.

示例输入

2
1 1 1 1 1 1 1 1 1
1 2 3 4 5 6 7 8 9

示例输出

Case 1: 1
Case 2: 72
dfs9!存在负数和相同的数,明显的剪枝条件只有横行竖列和是否为总和的1/3;
想开一个999999999的数组hash判重复可惜数组太大开不来,然后准备分层hash判重但是对于第一层是可以的第二层就错了,因为虽然第二层的某个组合我们搜索过,但是如果他们第一层的数据不一样,还是可能产生正解;
于是改变策略,对于第一层的3个产生完毕后哈希判重,后面两层先保证横行数列正确,最后把所有解保存下来每次判断解是否重复,
(第一层)3!*(二三层)6!=4320
#include<stdio.h>
#include<string.h>
int count,sum,num[10],hash[10],ans[10],res[10],visit[10],have[9][9][9],a[4321][10]; ans存放数字,res存放标号
int ok() //判断解是否重复
{int i,j,f;
 for (i=1;i<=count;i++)
 {f=1;
  for (j=1;j<=9;j++)
  if (ans[j]!=a[i][j]) {f=0;break;}
  if (f) return 0;
 }
 return 1;
}
void dfs(int step)
{int i;
 if (step==3)
 {if (have[hash[res[1]]][hash[res[2]]][hash[res[3]]]) return ;
          else have[hash[res[1]]][hash[res[2]]][hash[res[3]]]; //第一层不重复搜索
  if (ans[1]+ans[2]+ans[3]!=sum) return ;
 }
 if ((step==6)&&(ans[4]+ans[5]+ans[6]!=sum)) return ;
 if ((step==7)&&(ans[1]+ans[4]+ans[7]!=sum)) return ;
 if ((step==8)&&(ans[2]+ans[5]+ans[8]!=sum)) return ;
 if ((step==9)&&(ans[3]+ans[6]+ans[9]!=sum)) return ;
 if ((step==9)&&(ans[7]+ans[8]+ans[9]!=sum)) return ;
 if (step==9) {if (ok()) {++count;for (i=1;i<=9;i++) a[count][i]=ans[i];} return;}
 for (i=1;i<=9;i++)
 if (visit[i]==0)
 {visit[i]=1;
  ans[step+1]=num[i];
  res[step+1]=i;
  dfs(step+1);
  visit[i]=0;
 }
};
int main()
{int i,j,k,t,r;
 scanf("%d",&t);
 for (r=1;r<=t;r++)
 {
  sum=0; count=0;
  for (i=1;i<=9;i++)
  {scanf("%d",&num[i]);
   sum+=num[i];
  }
  memset(visit,0,sizeof(visit));
  memset(have,0,sizeof(have));
  for (i=1;i<9;i++)
  for (j=i+1;j<=9;j++)
  if (num[i]>num[j]) {k=num[i];num[i]=num[j];num[j]=k;}
  hash[1]=0;
  for (i=2;i<=9;i++)
  if (num[i]==num[i-1]) hash[i]=hash[i-1];  //计算hash值
                   else hash[i]=hash[i-1]+1;
  if (sum%3==0) {sum=sum/3;dfs(0);}
  printf("Case %d: %d\n",r,count);
 }
 return 0;
}

 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值