Particle

競技プログラミングについての雑記

VK Cup 2012 Qualification Round 2

A. Friends or Not
古い情報を上書きして行けば解けそうだけど、何故か解けない。

B. Matchmaker
yとbが同じになるところだけ考えれば良いです。一応コード載せておくけど、説明できない…

int y[1001],b[1001],yx[1001][1001];
vector<int> ba[1001];

int main(){
	int n,m;
	cin>>n>>m;
	
	for(int i=0;i<n;i++){
		int s,t;
		cin>>s>>t;
		y[t]++;
		yx[t][s]++;
	}
	for(int i=0;i<m;i++){
		int s,t;
		cin>>s>>t;
		b[t]++;
		ba[t].push_back(s);
	}
	
	int u=0,v=0;
	for(int i=1;i<=1000;i++){
		if(y[i]&&b[i]){
			u+=min(y[i],b[i]);
			for(int j=0,l=ba[i].size();j<l;j++){
				int co = ba[i][j];
				if(yx[i][co]){
					yx[i][co]--;
					v++;
				}
			}
		}
	}
	
	cout<<u<<' '<<v<<endl;
	return 0;
}

C. String Manipulation 1.0
BITを使えば解けますが、私は実装できません。

D. Palindrome pairs
回文を全部調べて、左端・右端を記録しておきます。回文を調べるときに中心を基準に調べると速いです。最後の計算では、式変形すると速く計算できます。
(a1*b2+a1*b3+..a1*bn + a2*b3+.. を a1*(b2からbnまでの和)+a2*(b3*bnまでの和).. と変形する)

string s;
int len;
long long ans,Left[2000],Right[2000];//Left:左側(右端),Right:右側(左端)

int main(){
	cin>>s;
	len = s.size();
	
	for(int i = 0; i < len; i++){
		for(int a = i,b = i; 0 <= a && b < len; a--,b++){
			if(s[a] == s[b]){
				Left[b]++;
				Right[a]++;
			}else{
				break;
			}
		}
		
		for(int a = i,b = i+1; 0 <= a && b < len; a--,b++){
			if(s[a] == s[b]){
				Left[b]++;
				Right[a]++;
			}else{
				break;
			}
		}
	}

	for(int i = 1; i < len-1; i++){
		Left[i] += Left[i-1];
	}
	
	for(int i = 0; i < len-1; i++){
		ans += Left[i]*Right[i+1];
	}
	
	cout<<ans<<endl;
	
	return 0;
}

E. Zebra Tower
ぼんやりと、どうすれば解けそうかは分かったけど、解けなかった。