您的位置:首页 > 其它

USACO 1.3

2011-11-16 08:20 141 查看
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表示,不然变量名在充分就杯具了。

映射数组,对另一个数组进行操作,避免其他的影响。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: