Codeforces Round #329 (Div. 2) (A, B)
tags: Codeforces
第一次做动态分的比赛,感觉好神奇.虽然比赛中只做出了两题(第一题还因为脑残写错数据类型跪了),不过还好rating还是从1415涨到了1494.
A. 2Char
题意:
从n个小写字母组成的单词中选择一些,使其中出现的字符不超过两种,问长度和最大为多少.
分析:
由于单词数不超过100,因此可以暴力所有字母的组合,取只包含这两种字母中一种或两种的单词,求得长度和,维护长度和的最大值就好了,不超过 26∗26∗100 次操作就能确定最大长度.
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#include <string>
using namespace std;
char dict[200][1200]; //存放单词
int ch[200][30]; //每个单词中的每种字母的个数
int cnt[200]; //每个单词中字母的种数
int len[200]; //每个单词的长度
int main()
{
int n;
memset(dict, 0, sizeof(dict));
memset(ch, 0, sizeof(ch));
memset(cnt, 0, sizeof(cnt));
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
scanf("%s", dict[i]);
for (int j = 0; dict[i][j] != '\0'; ++j)
{
if (ch[i][dict[i][j] - 'a'] == 0)
{
cnt[i]++;
}
ch[i][dict[i][j] - 'a']++;
len[i]++;
}
}
int maxlen = 0;
for (int i = 0; i < 26; i++)
{
for (int j = i; j < 26; j++)
{
int len_now = 0;
for (int p = 0; p < n; p++)
{
if (cnt[p] == 1 && (ch[p][i]>0 || ch[p][j]>0))
{
//单词中只有1种字母,且是i或j中的一种
len_now += len[p];
}
else if (cnt[p] == 2 && i != j && (ch[p][i]>0 && ch[p][j] > 0))
{
//单词中有2种字母,且分别是i和j(i!=j)
len_now += len[p];
}
}
if (len_now > maxlen)
maxlen = len_now;
}
}
printf("%d\n", maxlen);
return 0;
}
B. Anton and Lines
题意:
给定n条不同的直线(y=ax+b形式),问是这些直线否在x=(x1,x2)对应的区域内内有交点.
解析
实际上只需要对(x1,x2)范围内的线段进行处理,将所有线段按x=x1时的值排序,判断相邻的线段是否相交即可.因为若a,b,c三条直线相邻,且a,c相交于区域内,则b必定与a或c交于区域内,所以只要遍历所有线段,检查相邻的线段是否相交于区域内即可
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
#define min(a,b) a<b?a:b
#define max(a, b) a>b ? a : b
int n;
double x1, x2;
struct node
{
double y1;
double y2;
}nnode;
bool cmp(node a,node b)
{
if (a.y1 != b.y1)
return a.y1 < b.y1;
return a.y2 < b.y2;
}
bool check(node a,node b)
{
return (a.y1 - b.y1)*(a.y2 - b.y2) < 0;
}
int main()
{
vector<node> v;
scanf("%d", &n);
scanf("%lf%lf", &x1, &x2);
for (int i = 0; i < n; i++)
{
int k, b;
scanf("%d%d",&k,&b);
nnode.y1 = k*x1 + b;
nnode.y2 = k*x2 + b;
v.push_back(nnode);
}
sort(v.begin(), v.end(), cmp);
int sz = v.size();
int flg = 0;
for (int i = 1; i < sz; ++i)
{
if (check(v[i - 1], v[i]))
{
flg = 1;
break;
}
}
if (flg)
printf("yes\n");
else
printf("no\n");
return 0;
}
D. Happy Tree Party(还没写)
题意:
给定一棵有n( 2≤n≤200000 )个节点的树,每条边有一定的权值p(p>=1).有两种操作:
- 输入
1 a b Y
,询问a到b路径上的边的权值乘积m,输出Y/m - 输入
2 x y
将第x条边的权值修改为比原来p值小的值y