2012年"浪潮杯"山東省第三屆ACM大學生程式設計競賽(熱身賽)

滑頭鬼之亨發表於2012-06-02

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;
}

 

相關文章