USACO 1.4.4_combo
阿新 • • 發佈:2018-12-13
USACO官方給的是暴力搜尋,逐個判斷的思路,不涉及搜尋演算法需要的判重。 我這個題解主要是用的深搜思路,用一個vector陣列,精確構造滿足題意的組合,然後使用一個1,000,000大的visit陣列,記錄是否訪問過,使用空間換取時間。
/*
ID: cjn77881
LANG: C++
TASK: combo
*/
#include <stdio.h>
int N,x1,x2,x3,y1,y2,y3,idx,ans,a[3],vector[5]={-2,-1,0,1,2};
bool v[1000001];
void deal(int &x){
if (x>=N) x-=N;
if (x<0) x+=N;
}
int hash(int *a){ //簡單構造的雜湊函式,用空間換時間
return (a[0]*10000+a[1]*100+a[2]);
}
void dfs(int *a,int depth){
if (depth==3){
idx = hash(a);
if (!v[idx]){
ans++;
v[idx]=true;
// for (int i=0;i<3;i++) printf("%d ",a[i]); printf("\n");
}
return;
}
for (int i=0;i<5;i++) {
a[depth] +=vector[i]; deal(a[depth]);
dfs(a,depth+1);
a[depth]-=vector[i]; deal(a[depth]); //進行下一項前,先將a[depth]恢復原值
}
return;
}
int main(){
FILE *fin = fopen("combo.in","r");
FILE *fout = fopen("combo.out","w");
fscanf(fin,"%d\n",&N);
fscanf(fin,"%d %d %d",&x1,&x2,&x3);
fscanf (fin,"%d %d %d",&y1,&y2,&y3);
if (N==1){ //只有一個選項時,沒必要通過vector函式向左右移位了
vector[0]=0; vector[1]=0; vector[3]=0; vector[4]=0;
}
if (N==2){ //只有兩個選項時,通過vector函式向左右移位,一位就足矣
vector[0]=0; vector[4]=0;
}
x1--; x2--; x3--;
y1--; y2--; y3--;
a[0]=x1; a[1]=x2; a[2]=x3;
dfs(a,0);
a[0]=y1; a[1]=y2; a[2]=y3;
dfs(a,0);
printf("%d\n",ans);
fprintf(fout,"%d\n",ans);
return 0;
}