MDeath-Kid

- M I T & Y
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

USACO 1.3

Posted on 2011-11-16 08:20  MDeath-Kid  阅读(167)  评论(0编辑  收藏  举报

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表示,不然变量名在充分就杯具了。
  • 映射数组,对另一个数组进行操作,避免其他的影响。