连接:http://codeforces.com/problemset/problem/673/C
算法:枚举
题意:给定一个范围n,然后分别找到从1到n,这n个数最好的值可以出现在多少个区间。找到做好的值的方法是,在这个区间内出现的次数最多,当两个数出现的次数一样多的时候,做好的值为数值比较小的那一个。
思路:本题的枚举方法有点类似找到该数组的不同种区间,比如说5个数,区间可以这么划分{{1},{1,2},{1,2,3},{1, 2,3,4},{1, 2,3,4, 5},{2},{2, 3}, {2,3, 4}, {2,3, 4, 5},{3}, {3, 4}, {3, 4, 5}, {4}, {4, 5}, {5}},再用一个数组vis记录出现的最好数的区间个数, 用数组cnt来记录出现的个数,然后在这个区间内出现的次数最多,当两个数出现的次数一样多的时候,做好的值为数值比较小的那一个。
代码:
#include<stdio.h>
#include<string.h>
#include<map>
#include<iostream>
using namespace std;
#define MAXN 5050
int vis[MAXN], a[MAXN], cnt[MAXN];
int main(){
int n;
cin>>n;
for(int i = 1; i <= n; i++){
cin>>a[i];
}
int val;
memset(vis, 0, sizeof(vis));//初始化
for(int i = 1; i <= n; i++){
memset(cnt, 0, sizeof(cnt));//每次初始化cnt记录的数
val = a[i];//第一个数,最开始默认为最好的数
cnt[val]++;//个数加1
vis[val]++;//范围加1
for(int j = i+1; j <= n; j++){
cnt[a[j]]++;
if(cnt[a[j]] > cnt[val]){//a[j]的个数是最多的时候
val = a[j];
vis[val]++;
}
else if(cnt[a[j]] == cnt[val] && a[j] < val){//a[j]与val相等的时候,如果a[j]<val,最好的数就是a[j]
val = a[j];
vis[val]++;
}
else vis[val]++;//其他情况下开始加1,val就是最好的数
}
}
for(int i = 1; i <= n; i++){
if(i != 1)cout<<" ";
cout<<vis[i];
}
cout<<endl;
return 0;
}
连接:http://codeforces.com/problemset/problem/766/D
算法:并查集
题意:本题主要有两部分,给你一定的关系判断他们之间的关系是否有问题,任意单词之间有两种关系,同意词和反义词,如果这个词和某个词的既是同意词又是反义词,那么这就出现了矛盾。输出“NO”,否则输出“YES”。当判断完这些关系中是否出现问题,之后再判断两个词之间的关系,是同意词输出是1,反义词输出是0,如果没有关系的额话输出3。
思想:本题的思想采用的并查集和STL中的map,用字符串来映射数字分别为x, y,用i+n表示反义词,当k为1时如果x和y的反义词在一个区间有,那么就出现问题,如果k为2的时候,x与y是同意词,或者x的相反数与y的相反数是同意词那么就出现问题。
#include<stdio.h>
#include<string.h>
#include<map>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
#define MAXN 100005
map<string, int>ma;
int pre[MAXN*2];
int Find(int x)
{
if(pre[x]==x)
return x;
else return pre[x]=Find(pre[x]);
}
int main()
{
int m, n, q;
string a, b;
cin>>m>>n>>q;
for(int i = 0; i < m; i++)
{
cin>>a;
ma[a] = i;
}
for(int i = 0; i < m; i++)
{
pre[i] = i;
pre[i+m] = i+m;
}
int x, y, fx, fy;
while(n--)
{
int k;
cin>>k;
cin>>a>>b;
x = ma[a];
y = ma[b];
if(k == 1)
{
if(Find(x) == Find(y+m) || Find(x+m) == Find(y))
{
cout<<"NO"<<endl;
}
else
{
cout<<"YES"<<endl;
pre[Find(x)] = Find(y);
pre[Find(x+m)] = Find(y+m);
}
}
else
{
if(Find(x) == Find(y) || Find(x+m) == Find(y+m))
{
cout<<"NO"<<endl;
}
else
{
cout<<"YES"<<endl;
pre[Find(x)] = Find(y+m);
pre[Find(x+m)] = Find(y);
}
}
}
while(q--)
{
cin>>a>>b;
x = ma[a];
y = ma[b];
if(Find(x) == Find(y)|| Find(x+m) == Find(y+m))cout<<1<<endl;
else if(Find(x+m) == Find(y) || Find(x) == Find(y+m))cout<<2<<endl;
else cout<<3<<endl;
}
return 0;
}