Buy Lower, Buy Lower (buylow)
最长下降子序列,在计算方案数的时候用到大整数加法。
/* ID:### PROG:buylow LANG:C++ */ #include <iostream> #include <stdio.h> #include <memory.h> using namespace std; int a[5011],f[5011]; typedef int arr[500]; arr num[5010]; int b[5011]; bool u[5011]; int n; void init() { int i,j,k; freopen("buylow.in","r",stdin); freopen("buylow.out","w",stdout); n = 0; i = -1; scanf("%d",&k); while (k --) { scanf("%d",&j); if ( j != i) { a[++n] = j; } i = j; } a[++n] = -1; } void add(arr a,arr b) { int i,j,k; k = a[0]; if ( k < b[0] ) k = b[0]; for ( i = 1; i <= k; i++) a[i] +=b[i]; for ( i = 1; i <= k; i++) {a[i+1]+=a[i]/10;a[i] = a[i] % 10;} if (a[k+1] !=0) a[0] = k+1;else a[0] = k; } void solve() { int i,j,k,m; for ( i = 1; i <= n; i++) { memset(u,0,sizeof(u)); num[i][0] = 1; k = i; m = 0; for (j = i - 1; j; j--) { if (a[j] > a[i] ) if( f[j] > f[k] ) { k = j; b[m = 1] = j; }else if (f[j] == f[k]) b[++m] = j; } f[i] = f[k] + 1; if (f[i] == 1) num[i][0] = num[i][1] = 1; for ( j = 1; j <= m; j++) { for ( k = 1; k < j; k++) if (a[b[k]] == a[b[j]]) break; if ( k == j ) add(num[i],num[b[j]]); } } printf("%d ",f[n]-1); for ( i = num[n][0]; i ;i--) printf("%d",num[n][i]); printf("\n"); } int main() { init(); solve(); return 0; }
The Primes (prime3)
搜索题,卡了我好久。
这道题先筛选出符合条件的质数,然后按照一定顺序进行搜索。我先搜索第一行,第一列,两个对角线,第五行,然后计算第三行2,4个数,第五列,然后计算剩余的数,并检验是否符合条件。最后排序输出。
/* ID:### LANG:C++ PROG:prime3 */ #include <iostream> #include <algorithm> #include <stdio.h> #include <memory.h> using namespace std; bool b[100001]={}; int n,m; int w[5][5]; int ord[11]={}; int ord2[11]={}; int a[10000][5]; int sum = 0; int a2[10000][5]; int t; int tot = 0; int c[1000][5][5]; int d[1000]; void print2() { int i; int j =0; for ( i = 0; i < 5; i++) { j = j*10 +w[i][i]; } } bool cmp(int p,int q) { int i,j; for ( i = 0; i <5;i++) for ( j = 0; j < 5; j++) { if (c[p][i][j]<c[q][i][j] ) return 1;else if (c[p][i][j] >c[q][i][j]) return 0; } return 1; } void init() { freopen("prime3.in","r",stdin); freopen("prime3.out","w",stdout); int i,j,k; i = 2; for ( i = 0; i < 1000; i ++) d[i] = i; i = 2; while ( i < 100000 ) { if ( !b[i] ) { j = 2*i; while ( j < 100000) { b[j] = 1; j += i; } } i ++; } cin >> m >>n; for ( i = 10000; i < 100000; i++) { if (!b[i]) { j = i; k = 0; while ( j) {k += j % 10; j = j /10;} if ( k == m ) { sum ++; j = i; for ( k = 4; k >=0; k--) { a[sum][k] = j %10; j = j /10; } j = a[sum][0]; if ( ord[j] == 0 ) { ord[j] = sum; } } } } ord[10] = sum + 1; for ( i = 9; i; i--) if( ord[i] == 0 ) ord[i] = ord[i + 1]; k = 0; for ( i = 1; i <= sum; i++) { int flag = 0; for( j = 0;j < 5; j++) { int p = a[i][j]; if (p != 1&&p!=3&&p!=7&&p!=9) {flag = 1;break;} } if ( flag ) continue; k++; for ( j = 0; j < 5; j++) a2[k][j] = a[i][j]; if (ord2[a[i][0]] == 0) ord2[a[i][0]] = k; } ord2[10] = k + 1; for( i = 9; i ;i --) if( ord2[i] == 0) ord2[i] = ord2[i+1]; } void sa() { tot ++; for ( int i = 0; i < 5; i++) { for ( int j = 0; j < 5; j++) { c[tot][i][j] = w[i][j]; } } } void dfs (int vt) { int i,j,p,q,k,temp; if ( vt == 1) { for ( i = ord2[w[4][0]]; i < ord2[w[4][0] + 1]; i ++) { if ( w[4][4] == a2[i][4]) { w[4][1] = a2[i][1];w[4][2] = a2[i][2]; w[4][3] = a2[i][3]; w[2][1] = m - w[0][1] -w[1][1] -w[3][1]-w[4][1]; if (w[2][1] < 0||w[2][1] >9) continue; temp = 0;for ( k = 0; k < 5; k++) temp = temp*10+w[k][1]; if (b[temp]) continue; w[2][3] = m - w[0][3] - w[1][3] - w[3][3] - w[4][3]; if( w[2][3] < 0||w[2][3] >9) continue; temp = 0;for ( k = 0; k < 5; k++) temp = temp*10+w[k][3]; if (b[temp]) continue; w[2][4] = m - w[2][0] - w[2][1] - w[2][2] - w[2][3]; if (w[2][4] <0||w[2][4] > 9) continue; temp = 0;for ( k = 0; k < 5; k++) temp = temp*10+w[2][k]; if (b[temp]) continue; for ( j = ord2[w[0][4]]; j < ord2[w[0][4]+1]; j++) { if (w[2][4] == a2[j][2] && w[4][4] == a2[j][4]) { w[1][4] = a2[j][1];w[3][4] = a2[j][3]; w[1][2] = m - w[1][0]- w[1][1] - w[1][3] - w[1][4]; if ( w[1][2] < 0 ||w[1][2] >9) continue; temp = 0;for ( k = 0; k < 5; k++) temp = temp*10+w[1][k]; if (b[temp]) continue; w[3][2] = m -w[3][0] - w[3][1] - w[3][3] - w[3][4]; if( w[3][2] <0||w[3][2]>9) continue; temp = 0;for ( k = 0; k < 5; k++) temp = temp*10+w[3][k]; if (b[temp]) continue; temp = 0;for ( k = 0; k < 5; k++) temp = temp*10+w[k][2]; if (b[temp]) continue; if ( m == w[0][2] + w[1][2] + w[2][2] + w[3][2] + w[4][2]) sa(); } } } } }else {} } void solve() { int i,j,k,p,q; int flag = 0; for ( i = ord[n]; i < ord[n+1]; i++) { for ( k = 0; k < 5; k++){ w[0][k] = a[i][k]; if ( a[i][k] == 0) flag = 1;} if ( flag ) {flag = 0;continue;} for ( j = ord[n]; j < ord[n+1]; j++) { for ( k = 1; k < 5; k++){ w[k][0] = a[j][k]; if ( a[j][k] ==0) flag = 1;} if( flag ) {flag = 0;continue;} for ( p = ord[n] ; p < ord[n +1];p++) { for ( k = 1; k < 5; k++) w[k][k] = a[p][k]; for ( q = ord[w[4][0]]; q< ord[w[4][0] + 1]; q++) { if (a[q][2] == w[2][2] && a[q][4] == w[0][4]) { w[3][1] = a[q][1]; w[1][3] = a[q][3]; dfs (1); } } } } } } void print() { int i,j,k; sort(d+1,d+tot+1,cmp); for ( i = 1; i <= tot; i++) { for ( j = 0; j < 5; j++) { for( k = 0; k < 5; k ++) cout <<c[d[i]][j][k]; cout <<endl; } if ( i != tot) cout<<endl; } if ( tot == 0) cout <<"NONE"<<endl; } int main() { init(); solve(); print(); return 0; }
Street Race (race3)
先做一遍floyed,然后枚举每个点,删除它并从起点深搜,判断是否为unavoidable,如果从起点可以到达i并且从这个点也能到达i,则不满足第二问条件。
Letter Game (lgame)
最多只有两个单词进行组合。枚举就可以通过。
/* ID:### LANG:C++ PROG:lgame */ #include <iostream> #include <stdlib.h> #include <stdio.h> #include <fstream> #include <string> using namespace std; int m,n; int maxvalue = 0; int b[26]={}; int cost[]={2,5,4,4,1,6,5,5,1,7,6,3,5,2,3,5,7,2,1,2,4,6,6,7,5,7}; string s; string r[40000]; string rr[40000]; int fit(string w) { int c[26]; int i,j,k; k = 0; for ( i = 0; i < 26; i ++) c[i] = b[i]; for ( j = 0; j < w.length(); j++) { if ((--c[w[j]-97]) < 0) return 0; k += cost[w[j] - 97]; } return k; } void init() { n = m = 0; freopen("lgame.in","r",stdin); freopen("lgame.out","w",stdout); ifstream fd("lgame.dict"); cin>>s; int i,j,k; for ( i = 0; i < s.length(); i++) b[s[i]-97] ++; string s1=""; fd>>s1; while( s1 != ".") { if (fit(s1)) { rr[++n] = s1; } fd>>s1; } } void solve() { int i,j,k; for ( i = 1; i <= n; i++) { k = fit(rr[i]); if ( k >= maxvalue) { if ( k > maxvalue) {m = 0; maxvalue = k;} r[++m] = rr[i]; } for( j = i + 1; j <=n; j++) { k = fit(rr[i]+rr[j]); if ( k >= maxvalue) { if ( k > maxvalue) {m = 0; maxvalue = k;} r[++m] = rr[i]+" "+rr[j]; } } } cout << maxvalue <<endl; for ( i = 1; i <= m ;i++) cout<<r[i]<<endl; } int main() { init(); solve(); return 0; }