起来才发现昨晚打的是div3 = =
Codeforces Round #544 (Div. 3)
A题
题意
给两个时间点,h1:m1,h2:m2,求他们中间的时间是什么,24小时制,保证秒数时间差为偶数,输出为xx:xx,不足的用0补齐
假思路
int main()
{ // if(fopen("in.txt","r")) freopen("in.txt","r",stdin);
int T,n,m,k,i,sum,j,t,tmp;
int h1,h2,m1,m2;
scanf("%d:%d%d:%d",&h1,&m1,&h2,&m2);
int t1 = h1*60 + m1;
int t2 = h2*60 + m2;
t = t2 - t1;
// cout<<t<<endl;
t /= 2;
//cout<<t<<endl;
tmp = t/60;
int h = h1 + tmp;
m = (t - tmp*60 + m1 )%60;
printf("%02d:%02d\n",h,m);
return 0;
}
t为开始时间到中间时间的秒数,然后加起来一波操作,然后wa了
睡觉的时候想起来:
m那里如果刚好是60的话,h应该++
出错的例子是:
00:01
23:59
输出了11:00
应该是:12:00
正确思路
一个是上面提到的h++,做题的时候wa了一发 蒙了,就改了个思路,计算中间时刻从00:00开始的秒数,再化成时和秒
int main()
{ if(fopen("in.txt","r")) freopen("in.txt","r",stdin);
int T,n,m,k,i,sum,j,h,t,tmp;
int h1,h2,m1,m2;
scanf("%d:%d%d:%d",&h1,&m1,&h2,&m2);
int t1 = h1*60 + m1;
int t2 = h2*60 + m2;
t = t2 - t1;
// cout<<t<<endl;
t /= 2;
// cout<<t<<endl;
t1 += t;
// cout<<t1<<endl;
h = t1/60;
m = t1 - t1/60*60;
printf("%02d:%02d\n",h,m);
return 0;
}
B题
题意
给n个数字,一个k,要求两个两个数字搭配,使得这两个数字加起来是k的倍数,然后数字不可以重复用,问有多少个适合搭配的数字
思路
发现k比较小,先把n个数字mod k,变成0~k-1。他们搭配的方案最多有 k/2 + 1种。然后1和k-1搭配,2和k-2搭配。。。注意mod k = 0的数字的个数就直接加入答案,注意一下奇数个要 - 1 ,再注意一下k=6 , 3+3=6类似这种情况统计。
代码
int main()
{ if(fopen("in.txt","r")) freopen("in.txt","r",stdin);
int T,n,m,k,i,sum,j,t,tmp;
int cnt[105]={0},a[2*maxn];
scanf("%d%d",&n,&k);
for(i=0;i<n;i++){
a[i] = read();
cnt[a[i]%k]++;
}
ll ans = cnt[0]-(cnt[0]&1);
// cout<<ans<<endl;
for(i=1;i<=k/2;i++){
// cout<<i<<" "<<cnt[i]<<" "<<cnt[k-i]<<endl;
if(k-i!=i){
ans += min(cnt[i] , cnt[k-i])*2;
}else ans += cnt[i]-(cnt[i]&1);
}
printf("%d\n",ans);
return 0;
}
C题
题意
给出n个数字,在里面找集合,要求集合中的数字间相差不超过5,问适合条件的集合的元素最多有多少个。
假思路
= = 觉得div2 C题了,感觉是dp,写了个假的dp,结果后来发现不是。
思路
从小到大排序,然后用 upper_bound 找一找第一个比 a[ i ] + 5 大的数字在哪,然后减一下坐标,及时统计答案就行了。
int main()
{ if(fopen("in.txt","r")) freopen("in.txt","r",stdin);
int n,a[2*maxn],ans=-1,i,k;
scanf("%d",&n);
for(i=0;i<n;i++) a[i] = read();
sort(a,a+n);
for(i=0;i<n;i++){
k = upper_bound(a,a+n,a[i]+5)-(a+i);
// cout<<k<<endl;
ans = max(ans,k);
}
printf("%d\n",ans);
return 0;
}
D题
题意
给 n 组 a [ i ] 和 b [ i ],要求找到一个最合适的 d ,使得最多组 d * a [ i ] + b [ i ] = 0,输出最多有多少组。d 为实数。
思路1
比赛时候想的是统计使得 d * a [ i ] + b [ i ] = 0 成立的 d 的分子和分母,用gcd化简成最简形式,用pair<int,int>来存,用map< pair<int,int> , int >mp来存这些不同 d 的个数,然后遍历mp,来看看哪个 d 的个数最大,就是答案
不过细节有点问题,对于 a [ i ] == 0 && b [ i ] == 0 的情况,写的是mp[ make_pair(0,b[i]) ] ++,其实不对:对于全部实数d,都可以满足目标等式,不单是 d = 0 / b [ i ] 可以。醒来后补题,用flag记录这些情况,最后加在输出答案那里,就是最终答案。
= = 但这么做还是有漏洞:
就是 b [ i ] == 0 && a [ i ] != 0 的时候,mp[ make_pair(0,0) ] 应该++ ,d = 0 / 0 的情况应该统计,而这里如果直接gcd的话,统计的则是 d = 0 / ( a[i] / __gcd(0,a[i]),即 d = 0 / 1,就有问题了,所以还要特判
然后还是wa,wa在test 9 ,折腾几次发现是自己的快速读入出锅了= =、换成网上别的也不行,甚至wa在test 8。。。换成 cin 或者是 scanf 就过了。但之前一直都有用的。。应该没有写错吧。。test 9 太长了看不出哪里出问题。(知道自己快速读入出锅,有点缓不过来= =)
代码
ll read(){ // 贴一发出锅的快速读入,感觉没问题啊。。。。
//ios_base::sync_with_stdio(false);
//cin.tie(0);
ll x=0;char ch=getchar(); bool flag = false;
if(ch=='-') { flag = true; ch = getchar();}
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
if(flag) return -x; else return x;
}
int main()
{ if(fopen("in.txt","r")) freopen("in.txt","r",stdin);
int T,n,m,k,i,sum,j,t,tmp,flag=0;
int a[2*maxn],b[2*maxn];
map< pi , int > mp;
//cout<<__gcd(4,0)<<endl;
scanf("%d",&n);
for(i=0;i<n;i++) cin>>a[i];
for(i=0;i<n;i++){
cin>>b[i];
if(a[i]==0){
if(b[i]==0)flag++;
}else if(b[i]==0){
if(a[i]!=0)mp[P(0,0)]++;
}else{
t = b[i]/__gcd(a[i],b[i]);
tmp = a[i]/__gcd(a[i],b[i]);
// cout<<t<<" "<<tmp<<endl;
mp[P(t,tmp)]++;
}
}
map< pi ,int>::iterator it;
t = 0;
for(it = mp.begin();it!=mp.end();it++){
t = max(it->second,t);
}
printf("%d\n",t+flag);
return 0;
}
思路2
思路1没找出是快速读入出问题的时候,直接map存d的值了,思路差不多,不过也wa了= =,后来发现精度不够,要用 long double,不然:
2
999999999 1000000000
999999998 999999999
这一组输出的是2,应该输出的是1
然后快速读入这里也有问题,用回 scanf 就过了
代码
int a[2*maxn],b[2*maxn];
int main()
{ if(fopen("in.txt","r")) freopen("in.txt","r",stdin);
int T,n,m,k,i,sum,j,t,tmp,flag=0;
map< long double , int > mp;
scanf("%d",&n);
for(i=0;i<n;i++) scanf("%d",&a[i]);
for(i=0;i<n;i++){
scanf("%d",&b[i]);
if(a[i]==0){
if(b[i]==0) flag++;
}else{
long double tp = 1.0*b[i]/a[i];
mp[tp]++;
}
}
map< long double ,int>::iterator it;
t = 0;
for(it = mp.begin();it!=mp.end();it++){
t = max(it->second,t);
}
printf("%d\n",t+flag);
return 0;
}