题意:给你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;
}
题意:给你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