Codeforces Round #561 (Div. 2)- 水题(A B C)

A. Silent Classroom

题意:给你n个学生,把他们分成两个班,如果学生的首字母相同,则他们可以交流,问分成两个班后,可以交流的最小数。

思路:所有学生按照字典序排序,统计相同首字母的同学,总数 / 2,第一个班 总数 / 2人,第二个班 总数-总数 / 2人,然后计算和就行了(注意不是用组合数,(a,b )与 (b,a)是一种情况 ) n个人就是 (n-1)+(n-2)+(n-3)+ … +1;其实就是一个公差为1,首相为1,尾项为n-1的等差数列。

AC代码:

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int mmax=1e6+10;
const int eps=1e-9;
struct node{
 string name;
}s[105];
ll cmp(node a,node b)
{
	 if(a.name==b.name)
		  return a.name<b.name;
	return a.name<b.name;
	}
int main()
{
	 ll n;
	 while(cin>>n)
	{
		  for(int i=0;i<n;i++)
		  {
			   cin>>s[i].name;
		  }
		  sort(s,s+n,cmp);
		  ll ans=0,sum=0;
		  for(int i=0;i<n;i++)
		  {
		   	if(s[i].name[0]==s[i+1].name[0])
		    		ans++;
			   else
			   {
			  	ll num0=(ans+1)/2;
			    	ll num1=ans+1-num0;
			   	 ll sum0=0,sum1=0;
			    for(int i=1;i<num0;i++)
			    	 sum0+=i;
			    for(int i=1;i<num1;i++)
			  	   sum1+=i;
			    sum+=(sum0+sum1);
			    ans=0;
			   } 
	 		 }
		  	cout<<sum<<endl; 
	 }
 	return 0;
}

B. All the Vowels Please
题意:给你一个数k 让你求出n行m列,这n行m列的每一行每一列必须出现“a e i o u”.

思路:要想每一行每一列都有元音字母最少为5行5列。用一个while循环判断他的行数和列数是否满足。然后赋值就行了。str【(i+j)%m】=s[i%m] s=“aeiou”;
s[i%m] 就是第一行为 a 第二行为e 第三行为i …
这样就先满足每一列元音字母至少出现一次,然后看每一行,只需要让这一行的字母出现在不同行就行了。就是上面的式子。
AC代码:

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int mmax=1e6+10;
char str[105][105];
int main()
{
 	string s="aeiou";
 	ll k;
 	while(cin>>k)
	 {
 		 int m=(int)sqrt(k);
 		 while(k%m!=0) m--;
 		 int n=k/m;
 		 if(min(n,m)<5)
  		{
   			cout<<"-1"<<endl;
  			 continue;
		  } 
  		 else{
  		  for(int i=0;i<m;i++)
   		 {
     			for(int j=0;j<n;j++)
    			 {
    			  str[(i+j)%m][j]=s[i%5];
    			 }
    		}
    		
   		for(int i=0;i<m;i++)
   		 {
    			 for(int j=0;j<n;j++)
  			   {
     				 cout<<str[i][j];
    			  }
  		  }
  		  cout<<endl;
  	 }
 }	
 return 0;
 } 

C. A Tale of Two Lands

题意:给你n个数,选两个数x和y ,在数轴上满足 |x |和|y| 在|x-y| 和 |x+y| 的内部,包括端点,问一共多少组。

先找下规律:
1 2 3 4 5 6 7 8 9 10
这10个数
从1开始看,可以和1 匹配的只有2
2 可以和2匹配的有3 4 ,当然1也可以,但是上一步算过了,所以后面的数只看他后面的数,不看前面的。
3 可以和3匹配的有4 5 6
4 可以和4匹配的有5 6 7 8

你可以看出来,从小到大开始贪心,只需要看比他大的数, 这个数可以匹配的是<=这个数的两倍的数, 这样就找比他两倍大的数-i-1。

思路,把所有数取绝对值,sort一下(从小到大排序),用c++的upper_bound()找第一个比这个数大两倍的数-i-1,因为你统计的是比他大的所以要-1,你还得把他本身及他之前的数的坐标减点,最后用ans统计数量就ok了。

AC代码

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int  mmax=1e6+10;
ll a[mmax],n;
int main()
{
	 while(cin>>n)
	 {
		  ll b;
		 for(int i=1;i<=n;i++)
  		{
   			cin>>b;
   			a[i]=abs(b);
 		 }
  		sort(a+1,a+1+n);
  		ll ans=0;
  		for(int i=1;i<=n;i++)
  		{
  			 ans+=(upper_bound(a+1,a+1+n,a[i]*2)-a)-i-1;
  		}
  		cout<<ans<<endl;
 	}
 return 0;
 } 

总结:感觉刚开始看题没思路,一眼看不出来啥思路,得想好久,做题还是太少,还的坚持打cf,好好练练英语,我还没读懂题意,大佬们已经AC了。
- - - 2019.5.18 11:36

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

aaHua_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值