SRM 562 比赛总结

第一次参加TopCoder的SRM,时间是美国时间21点,北京时间10点(昨天),所以时间还是比较合适的。因为自己本身就是Not Rated,所以被分到了division 2。

最后提交了2题,不过很让人伤心的是,由于TopCoder本身的系统出了点问题,所以比赛结果宣布无效。。。。。。所以我现在还是Not Rated,好伤心……

第一题水题,排序然后判断一下就好了,最后也如预期的Pass System Test

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#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>

using namespace std;

class CucumberMarket {
public:
	string check(vector <int>, int, int);
};

string CucumberMarket::check(vector <int> price, int budget, int k) {
	int len=price.size();
	sort(price.begin(),price.end());
	int cost=0;
	for(int i=0;i<k;i++){
		cost+=price[len-1-i];
	}
	if(budget>=cost)
		return "YES";
	else return "NO";
}


//Powered by [KawigiEdit] 2.0!

第二题一开始没什么思路,后来发现方块都是在对角线上移动的,所以按照对角线进行搜索统计即可,为了让搜索顺序变成对角线,搞了接近40分钟。。。。最后五个测试样例全部都通过了,于是submit,也没人challenge,但是却Fail System Test,后来我又仔细想了想,原来是初始化错了,坑爹啊。。。做题太不仔细了。。。


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#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>

using namespace std;

class PastingPaintingDivTwo {
public:
	long long countColors(vector <string>, int);
};

long long PastingPaintingDivTwo::countColors(vector <string> clipboard, int T) {
	int row=clipboard.size();
	int col=clipboard[0].size();
	int begin=-(col-1);
	int end=(col-1);//应该是 end=(row-1);  才对。。。 血泪教训啊。。。
	long long counter[200];
	for(int i=0;i<200;i++)
		counter[i]=0;
	long long result=0;
	for(int k=begin;k<=0;k++){		
		int i=0;
		int j=i-k;
		bool find_begin=false;
		int end_position=-1;
		for(i=0;i<row;i++){
			j=i-k;
			if(j>=col)
				break;
			if(clipboard[i][j]=='B'){
				if(find_begin==false){
					end_position=i+T;
					counter[k+col]+=T;
				}
				find_begin=true;
				counter[k+col]+=min((i+T)-end_position,T);
				end_position=i+T;
			}
		}
	}
	for(int k=1;k<=end;k++){
		int j=0;
		int i=j+k;
		bool find_begin=false;
		int end_position=-1;
		for(j=0;j<col;j++){
			i=j+k;
			if(i>=row)
				break;
			if(clipboard[i][j]=='B'){
				if(find_begin==false){
					end_position=i+T;
					counter[k+col]+=T;
				}
				find_begin=true;
				counter[k+col]+=min((i+T)-end_position,T);
				end_position=i+T;
			}
		}
	}
	for(int i=0;i<200;i++){					
			result+=counter[i];		
	}
	return result;
}


//Powered by [KawigiEdit] 2.0!

那两个长长的for循环就是在沿对角线遍历,不过写的太麻烦了,其实可以很简单的。

Division2_problem3: RandomOption

分析:比赛的时候愣是没看懂题意(囧……),这道题和俄罗斯方块的游戏比较像,就是一堆方块一层一层地落下来,是有关概率论的(我觉得自己白学概率统计了……)。

一种思路是进行递归,将原问题分解为一系列的子问题,并且设定好边界条件,可惜在数据范围最大的时候会超时。

优化的方法就是备忘录形式的动态规划,记录一些已经计算出来的概率值即可。动规优化后,原先超出2s时限的数据,30ms可得到正确结果。

为了进一步优化,可以采用位操作来表示集合的组成。(我发现自从做了datalab之后,对位操作变得明显熟练了……)。

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#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<iomanip>

using namespace std;

class RandomOption {
public:
	int len;
	int key;
	bool check[20][20];
	double dp[1<<14][15];
	double getProbability(int, vector <int>, vector <int>);
	double dfs(int remain, int last, int t);
};

double RandomOption::getProbability(int keyCount, vector <int> badLane1, vector <int> badLane2) {
	double res=0;
	len=badLane1.size();
	key=keyCount;
	//initialize variables
	memset(check,true,sizeof(check));
	for(int i=0;i<len;i++){
		check[badLane1[i]][badLane2[i]]=false;
		check[badLane2[i]][badLane1[i]]=false;
	}
	for(int i=0;i<(1<<14);i++)
	for(int j=0;j<15;j++)
		dp[i][j]=-1;
	
	int begin=(1<<keyCount)-1;
	res=dfs(begin, keyCount, keyCount);
	return res;
}

double RandomOption::dfs(int remain, int last, int t){
	//boundary conditions
	if(remain==0 || t==0)
		return 1.0;
	if(dp[remain][last]!=-1)
		return dp[remain][last];
	
	double result=0;
	for(int i=0;i<key;i++){
		if( ((1<<i)&remain) && check[i][last]==true){
			result += (1.0/t)*dfs(remain&(~(1<<i)), i, t-1);
		}
	}
	dp[remain][last]=result;
	return result;
}

//<%:testing-code%>
//Powered by [KawigiEdit] 2.0!


唉,还是不够仔细,得认真吸取教训。不过这种比赛还确实挺好玩的 ,有时间可以参加一下,不过美国时间的白天几乎总是北京时间的半夜,这点让人不太爽。


嗯嗯,加油~~


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值