Coderforces 296 Div2
A题背景:竟然没有考虑到数据有1e12这么大,中间应该用取余代替频繁的加减,比如30和3,就不用频繁的减三了,直接取余3即可!
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define M 1009
#define INF 1e9
#define LL long long int
using namespace std;
int main(void){
LL count=0,a,b;
scanf("%I64d%I64d",&a,&b);
while(true){
if(a < b) swap(a,b);
if(b == 0) break;
if(a == b) {count++;break;}
if(b==1){count+=a;break;}
count+=a/b;
a=a%b;
}
printf("%I64d",count);
return 0;
}
B题:一道思想很巧妙的题,暴力方法O(n^2)超时,用set优化了查找之后O(nlogn)超时,最后无计可施看答案。。。
思路:这个最大的巧妙点是字符串虽然可以很长,但是元素是由小写字母组成的只有26种,而上下不相同的字母组成最多只有26*26种,所以用一个C[26][26]来记录每一种可能不同字母对出现的位置,这样如果有C[i][j],C[j][i]同时存在,就可以达到减少两个的效果了。
我的代码:
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#define M 200009
#define INF 1e9
using namespace std;
char str1[M],str2[M];
int A[26],B[26],C[26][26];
int main(void){
int n,ans=0;
scanf("%d%s%s",&n,str1,str2);
for(int i=0;i < n;i++)
if(str1[i] != str2[i])
ans++,A[str1[i]-'a']=i+1,B[str2[i]-'a']=i+1,C[str1[i]-'a'][str2[i]-'a']=i+1;
for(int i=0;i <26;i++){
for(int j=0;j < 26;j++){
if(C[i][j] && C[j][i]){
printf("%d\n%d %d\n",ans-2,C[i][j],C[j][i]);
return 0;
}
}
}
for(int i=0;i < 26;i++) if(A[i] && B[i]){printf("%d\n%d %d\n",ans-1,A[i],B[i]);return 0;}
printf("%d\n-1 -1\n",ans);
return 0;
}
C题:背景:比赛的时候暴力模拟O(n^2)的算法果断超时,只是对set用的不熟,后来看了别人用set做出来的,也就写了,鉴于set和map都是十分高效的数据结构虽然自己还写不出来
,学会用STL也是好的。
然后新知道的一些知识:
equal_range(v)函数返回一个pair类型,first为大于或等于v的第一个数,second为大于v的第一个数//类似于同时使用lower_bound(key_value),upper_bound(key_value)可以来高
效的查找。
iterator类不能减一,可以自增自减。
思路:用两个set来储存长和高的断点,两个multiset来储存长和高的长度(因为可能出现多个长度相同的点),这样进行模拟即可。这里有一点值得注意的地方:multiset进行
erase(key_value)操作时,是删除所有该值!
易错:
int a=INF,b=10000;
LL x=a*b;//这个是错误的,表达式右边全是int,不会因为赋值左边是LL而高级化。
我的代码:
#include <set>
#include <stack>
#include <queue>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define M 10
#define INF 0x3fffffff
#define LL long long int
using namespace std;
int main(void){
int length,width,t;
scanf("%d%d%d%*c",&length,&width,&t);
set<int,greater<int> > l,w;
l.insert(0);
l.insert(length);
w.insert(0);
w.insert(width);
multiset<int,greater<int> > ml,mw;
ml.insert(length);
mw.insert(width);
set<int,greater<int> >::iterator it_set1,it_set2,it_set3;
multiset<int,greater<int> >::iterator it_multiset1,it_multiset2;
while(t--){
char c;
int x;
scanf("%c %d%*c",&c,&x);
if(c == 'H'){
w.insert(x);
it_set2=it_set1=it_set3=w.find(x);
it_set1--;
it_set2++;
it_multiset1=mw.find(*it_set1-*it_set2);
mw.erase(it_multiset1);
mw.insert(*it_set1-*it_set3);
mw.insert(*it_set3-*it_set2);
}else{
l.insert(x);
it_set2=it_set1=it_set3=l.find(x);
it_set1--;
it_set2++;
it_multiset1=ml.find(*it_set1-*it_set2);
ml.erase(it_multiset1);
ml.insert(*it_set1-*it_set3);
ml.insert(*it_set3-*it_set2);
}
it_multiset1=ml.begin();
it_multiset2=mw.begin();
//cout << ml.count(2) << endl;
//cout << *it_multiset1 << " " << *it_multiset2 << endl;
LL a=(LL)*it_multiset1;
LL b=(LL)*it_multiset2;
LL xx=a*b;
printf("%I64d\n",xx);
}
return 0;
}