USACO 2013 March contest Bronze level 总结


 

边听音乐边吃东西边比赛……规定时间是4小时,我也就做了不到2小时,测了样例就直接提交了,等了很久很久终于出成绩了……最后967分(满分1000),最后一题有一组数据错了,其他都正确,顺利晋级Silver level~~

 

Problem 1:CowRace

大意是小牛赛跑,不同时段的速度有所不同,问领先者发生了几次更换。

我是一个时间单位一个时间单位得去模拟的,总时间不长,所以还可以接受。需要注意的边界情况就是:两头牛齐头并进的时候,此时并没有发生领先者的更换;二是最开始的时候,也不算在领先者更换的范围之内。

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <string.h>
using namespace std;

int main(){
	freopen("cowrace.in", "r", stdin);
	freopen("cowrace.out", "w", stdout);
	int n, m, t;
	//speed and time
	pair<int, int> node1[1005], node2[1005];
	int res = 0;
	cin>>n>>m;
	//total time
	t = 0;
	int leader = -1;
	for(int i=0; i<n; i++){
		cin>>node1[i].first>>node1[i].second;
		t += node1[i].second;
	}
	//cout<<"t: "<<t<<endl;
	for(int i=0; i<m; i++)
		cin>>node2[i].first>>node2[i].second;
	int pos1 = 0, ptr1 = 0;
	int pos2 = 0, ptr2 = 0;
	for(int i=1; i<=t; i++){
		if(node1[ptr1].second == 0)
			ptr1++;						
		node1[ptr1].second--;
		pos1 += node1[ptr1].first;
		
		//second cow
		if(node2[ptr2].second == 0)
			ptr2++;
		node2[ptr2].second--;
		pos2 += node2[ptr2].first;
		//cout<<"pos1: "<<pos1<<" pos2: "<<pos2<<endl;
		if(leader == -1){
			if(pos1 > pos2)
				leader = 1;
			else if(pos1 < pos2)
				leader = 2;
		}
		else if(leader == 1){
			if(pos2 > pos1){
				res++;
				leader = 2;
			}			
		}
		else if(leader == 2){
			if(pos1 > pos2){
				res++;
				leader = 1;
			}
		}//end else if
		//cout<<"leader: "<<leader<<endl;
	}//end for loop
	cout<<res<<endl;
	//system("pause");
	return 0;
}

 


Problem2:Breed Proximity

大意是一群牛(很好奇美国人怎么这么喜欢拿牛开涮……)站在一起,每头牛都有一个ID编号,要求出间距小于给定值并且最大的ID号。

最朴素的办法自然是去循环枚举,但牛的数目可以达到50000,O(n*K)的复杂度偏大。我的办法是先进行排序,按照ID从小到大拍,相同ID的按照原始位置排序。然后从后往前进行扫描,找到第一对间隔小于K的牛即为最终结果,扫描到头还没发现则不存在解,复杂度为O(nlgn)。

 

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <string.h>
#include <stdlib.h>
using namespace std;

struct Node{
	int pos;
	int id;
};
Node node[50005];

//sorting
int cmp(const void *ele1, const void *ele2){
	Node* p1=(Node *)ele1;
	Node* p2=(Node *)ele2;
	if((p1->id) == (p2->id))
		return (p1->pos)-(p2->pos);
	else return (p1->id)-(p2->id);
}

int main(){
	freopen("proximity.in", "r", stdin);
	freopen("proximity.out", "w", stdout);
	int n,k;
	cin>>n>>k;
	for(int i=0; i<n; i++){
		cin>>node[i].id;
		node[i].pos = i;
	}
	qsort(node, n, sizeof(Node), cmp);
	int res = -1;
	int last = -1;
	int large=0, small=0;
	for(int i=n-1; i>0; i--){
		if(res >= node[i].id)
			break;
		if(node[i].id == node[i-1].id){
			if(abs(node[i].pos-node[i-1].pos) <= k)
				res = max(res, node[i].id);
		}
	}
	cout<<res<<endl;
	//system("pause");
	return 0;
}


Problem3:

又是牛……给出各对牛之间的关系(相同品种或者不同品种),然后求共有多少可能的品种组合。

最简单的办法是枚举所有可能性,但3^15是1s内算不完的,考虑到对称性,可以假定第一头牛的品种,最后结果乘以3即可。我想到的另一个优化办法就是:如果一头牛没有说明和其他牛的关系,那么它就可以取3中不同的值,在最终的结果中起到了乘以3的作用。对于其他的,可以建成一个无向图,用floyd算法检查是否存在矛盾(利用“相同品种”具有传递性,不同品种则不具有传递性),若条件有矛盾则结果为0。然后深度搜索来枚举剩下的牛即可。

一开始提交的代码错了一个数据,后来发现是在floyd算法更新时漏了两种情况:如果A和B品种相同,B和C品种不同,那么A和C品种一定不同……另一种情况类似,是A、B不同,B、C相同。

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <string.h>
using namespace std;


bool flag[20];
vector<int> choice[20];
int multiple = 3;
int n, k, relation[16][16];
int res = 0;
int ans[20];
void dfs(int index);

int main(){
	//freopen("assign.in", "r", stdin);
	//freopen("assign.out", "w", stdout);

	memset(ans, 0, sizeof(ans));
	memset(relation, 0, sizeof(relation));
	for(int i=0; i<16; i++)
		relation[i][i] = 1;
	cin>>n>>k;
	for(int i=0; i<k; i++){
		int x, y;
		char str;
		cin>>str>>x>>y;
		x--; y--;
		if(str == 'S'){
			relation[x][y] = 1;
			relation[y][x] = 1;
		}
		else if(str == 'D'){
			relation[x][y] = -1;
			relation[y][x] = -1;
		}
	}
	//update status
	for(int i=0; i<n; i++)
	for(int j=0; j<n; j++)
	for(int k=0; k<n; k++){
		if(relation[j][i] == 1 && relation[i][k] == 1){
			if(relation[j][k] == -1){
				cout<<0<<endl;
				return 0;
			}
			else relation[j][k] = 1;
		}
		// I forgot these two relaations ><
		if(relation[j][i]==1 && relation[i][k]==-1){
			if(relation[j][k]==1){
				cout<<0<<endl;
				return 0;
			}
			else relation[j][k] = -1;
		}
		if(relation[j][i]==-1 && relation[i][k]==1){
			if(relation[j][k]==1){
				cout<<0<<endl;
				return 0;
			}
			else relation[j][k] = -1;
		}
	}
	
	
	memset(flag, true, sizeof(flag));
	flag[0] = false;
	for(int i=1; i<n; i++){
		if(relation[0][i] == -1){
			choice[i].push_back(1);
			choice[i].push_back(2);
		}
		else if(relation[0][i] == 1)
			flag[i] = false;
		else{
			choice[i].push_back(0);
			choice[i].push_back(1);
			choice[i].push_back(2);
		}
	}
	for(int i=0; i<n; i++){
		if(flag[i] == false)
			continue;
		flag[i] = false;
		for(int k=0; k<n; k++){
			if((i!=k) && (relation[i][k]!=0))
				flag[i] = true;
		}
		if(flag[i] == false)
			multiple = multiple*3;
	}	
	//cout<<"multiple: "<<multiple<<endl;
	dfs(0);
	res = res*multiple;
	cout<<res<<endl;
	system("pause");
	return 0;
}

void dfs(int index){
	if(index >= n){
		res++;
		return;
	}
	if(flag[index] == false){
		dfs(index+1);
		return;
	}
	int len = choice[index].size();
	for(int i=0; i<len; i++){
		ans[index] = choice[index][i];
		bool check = true;
		for(int j=0; j<index; j++){
			if(flag[j] == false)
				continue;
			if(relation[index][j]==1 && ans[index]!=ans[j]){
				check = false;
				break;
			}
			else if(relation[index][j]==-1 && ans[index]==ans[j]){
				check = false;
				break;
			}
		}//end for loop
		if(check == true){
			dfs(index+1);
		}
	}
	return;
}



你可能感兴趣的:(USACO 2013 March contest Bronze level 总结)