PROB Mixing Milk [ANALYSIS] ---- 最常见的一种贪心了吧,没啥好说的。
analysis 里面:
//很是犀利的想法 for(i=0;i<M;i++) { fscanf(in, "%d %d", &(price), &(amount)); amount_for_price[price]+=amount; }
PROB Barn Repair [ANALYSIS] ---- 贪心,有最大的木板就一块的时候进行倒推。
priority_queue<int> Q; int M,S,C; int a[MAXN]={0}; int main() { FOPENTI FOPENTO SCFT(M,S,C); F(i,C) SCF(a[i]); sort(a,a+C); int L=a[0],R=a[C-1]; FOR(i,1,C-1) { if(a[i] - a[i-1] > 1) { Q.push(a[i] - a[i-1] - 1); } } int sum = R - L + 1; M--; while((!Q.empty()) && M --) { //DB(Q.top()); sum -= Q.top(); Q.pop(); } PCFLN(sum); }
PROB Calf Flac [ANALYSIS] -----感觉这个题目还是比较有想头的。细节看代码。
// solution 1 枚举起点,枚举终点,判断回文 O(n^3) // solution 2 枚举中间的一个点,向左向右判断回文 O(n^2) // solution 3 DP,非严格DP,挺没意思的,虽然数据能过,但是不存在O(n)的算法。 // solution 4 正在想KMP + 后缀树的combine。。。。。= = = /* solution 2: 1 控制输入 2 hash出来只含有字母的一个int 数组 3 分奇偶开始枚举搜索,每次记录回文长度和最大值 */ char ss[MAXN]; int hashs[MAXN],lens; bool equal(int a,int b) { if(abs(ss[a] - ss[b]) ==0 || abs(ss[a] - ss[b]) ==32) return 1; return 0; } int is_palind(int ooo) { int i = ooo ,j = ooo ; while((i>=0 && j< lens) && equal(hashs[--i],hashs[++j])); return ooo - i - 1; } int is_palind_even(int ooo) { int i = ooo,j = ooo + 1; while((i>=0 && j< lens) && equal(hashs[i--],hashs[j++])); return ooo - i - 1; } int main() { //FOPEN FOPENTI FOPENTO int len=0; char tmp; // 1 while((tmp=getchar()) != EOF) ss[len++] = tmp; //puts(ss); lens=0; // 2 F(i,len) { if((ss[i] >='A' && ss[i] <='Z') || (ss[i] >='a' && ss[i] <='z')) { hashs[lens++] = i; } } int ans = INT_MIN,Beg,End; // 3 // odd for(int i = 1;i<lens;i++) { // 扩散的搜索 在 hashs 数组里 int lle = is_palind(i); if(ans < (lle * 2 + 1)) { ans = (lle * 2 + 1); Beg = hashs[i - lle]; End = hashs[i + lle]; } } // even for(int i = 0;i<lens-1;i++) { int lle = is_palind_even(i); if(ans < (lle * 2)) { ans = lle * 2; Beg = hashs[i - lle + 1]; End = hashs[i + lle]; } } PCFLN(ans); FOR(i,Beg,End) putchar(ss[i]); puts(""); }
PROB Prime Cryptarithm [ANALYSIS] ---- 一次水掉了,DFS枚举+判断。
// solution 1 DFS 枚举 总共 9^5 情况,每次判断 3 次 可以过 /* solution 1 1 DFS 枚举每一位 2 写一个判断函数判断每个能用吗 */ int mat[10], n, ans[10],has[10],kacs; int a,b,c,p,q; bool hash_num(int a) { while(a) { if(! has[a%10]) return 0; a /= 10; } return 1; } bool is_ok() { int num1 = a * 100 + b * 10 + c; int num2 = p * 10 + q; int ans1 = num1 * q; if(ans1 > 999) return 0; if(!hash_num(ans1)) return 0; int ans2 = num1 * p; if(ans2 > 999) return 0; if(!hash_num(ans2)) return 0; if(num1 * num2 > 9999) return 0; if(!hash_num(num1 * num2)) return 0; return 1; } void DFS(int x) { if(x == 6) { a = ans[1]; b = ans[2]; c = ans[3]; p = ans[4]; q = ans[5]; if(is_ok()) kacs++; return; } F(i,n) { ans[x] = mat[i]; DFS(x + 1); } } int main() { //FOPEN FOPENTI FOPENTO SET(has,0);kacs=0; SCF(n); F(i,n){ SCF(mat[i]); has[mat[i]]=1; } DFS(1); PCFLN(kacs); }
不得不说,上篇翻译的文章教育了我很多!下面继续翻译。
1.3 小结:
- 需要到有序整数的时候可化为整数数组的hash。
- 每次设计到数组下标运算的时候注意越界的情况!!!
- 以后搜索的深度统一用depth表示,不然变量名在充分就杯具了。
- 映射数组,对另一个数组进行操作,避免其他的影响。