Codeforces Round #329(Div2)

时间:2024-09-15 11:04:20

CodeForces 593A

题意:n个字符串,选一些字符串,在这些字符串中使得不同字母最多有两个,求满足这个条件可选得的最多字母个数。

思路:用c[i][j]统计文章中只有i,j对应两个字母出现的字符串的长度和。

c[i][i]表示只有一个字母字符串的累计长度。

c[i][j]  i!=j时:i>j  i<-->j i与j交换。

统计完以后,i,j 0->26.   i==j   ans=max(max,c[i][i])      i!=j     ans=max(max,c[i][j]+c[i][i]+c[j][j])

注意:不能直接暴力,存下每个字符串出现不超过两个不同的字母,再进行两重循环判断,这样比较复杂,并且answer不对。

代码:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std; int n,c[][],len;
char s[]; void deal()
{
len=strlen(s);
int f=,x,y,z;
for(int j=;j<len;j++)
{
z=s[j]-'a';
if(f==)
{
x=z;
f++;
}
else if(f==&&x!=z)
{
y=z;
f++;
}
else if(f==&&x!=z&&y!=z)
{
f++;
break;
}
}
if(f==)
c[x][x]+=len;
else if(f==)
{
if(y<x)
{
int t=x;x=y;y=t;
}
c[x][y]+=len;
}
} int countt()
{
int maxx=;
for(int i=;i<;i++)
for(int j=i;j<;j++)
{
if(i!=j)
maxx=max(maxx,c[i][j]+c[i][i]+c[j][j]);
else
maxx=max(maxx,c[i][j]);
}
return maxx;
} int main()
{
while(~scanf("%d",&n))
{
memset(c,,sizeof(c));
for(int i=;i<n;i++)
{
scanf("%s",s);
deal();
}
printf("%d\n",countt());
}
return ;
}

CodeForces 593B

题意:在一个坐标中,给定x1,x2.为一个区间范围,给出n条线的Ki,Bi. Yi=Xi*Ki+Bi    x1<Xi<x2.求这些线在x1,x2中间是否有交点。

思路:可以求出每条线与x1,x2的交点,即Y的取值范围。

例:r1,r2与x1分别交点L1,L2,与x2分别交点R1,R2。两条线相交,必须满足:L1<L2&&R1>R2  ||  L1>L2&&R1<R2

数据n范围为1e5,直接暴力比较n^2会超时。可利用sort()排序,nlogn. 在排序中对两条线的端点进行判断标记即可

注意:数据范围!!!!

代码:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=1e5+; int n,x1,x2,flag;
struct node
{
int l,r;
}p[maxn]; bool cmp(node a,node b)
{
if((a.l<b.l&&a.r>b.r)||(a.r<b.r&&a.l>b.l))
flag=;
if(a.l==b.l)
return a.r<b.r;
return a.l<b.l;
} int main()
{
int x,y;
while(~scanf("%d",&n))
{
flag=;
scanf("%d%d",&x1,&x2);
for(int i=;i<n;i++)
{
scanf("%d%d",&x,&y);
p[i].l=x*x1+y;
p[i].r=x*x2+y;
}
sort(p,p+n,cmp);
printf("%s\n",flag==?"YES":"NO");
}
return ;
}