A题并查集
题目大意: 给你n个用户和m个组,让你求出如果第i个人传播消息,会有几个人知道
套并查集模板
http://codeforces.com/contest/1167/problem/C
代码如下
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
int f[maxn];
int v[maxn];
int find(int x)
{
if(x==f[x])
return x;
else
{
f[x]=find(f[x]);
return f[x];
}
}
void hebing(int x,int y)
{
x=find(x);
y=find(y);
if(x==y)
return;
f[y]=x;
v[x]+=v[y];
}
int main()
{
int n,m,i,j,k,a,b;
cin>>n>>m;
for(i=1;i<=n;i++)
{
f[i]=i;
v[i]=1;
}
for(i=1;i<=m;i++)
{
cin>>k;
if(k>0)
{
cin>>a;
{
for(j=2;j<=k;j++)
{
cin>>b;
hebing(a,b);
}
}
}
}
cout<<v[find(1)];
for(i=2;i<=n;i++)
cout<<" "<<v[find(i)];
cout<<endl;
return 0;
}
/*#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
int f[maxn];
int v[maxn];
int find(int x)
{
if(x==f[x])
return x;
else
{
f[x]=find(f[x]);
return f[x];
}
}
void hebing(int x,int y)
{
x=find(x);
y=find(y);
if(x==y)
return;
else
{
if(v[x]<v[y])
{
f[x]=y;
v[y]+=v[x];
}
else
{
f[y]=x;
v[x]+=v[y];
}
}
}
int main()
{
int n,m,i,j,k,a,b;
cin>>n>>m;
for(i=1;i<=n;i++)
{
f[i]=i;
v[i]=1;
}
for(i=1;i<=m;i++)
{
cin>>k;
if(k>0)
{
cin>>a;
{
for(j=2;j<=k;j++)
{
cin>>b;
hebing(a,b);
}
}
}
}
cout<<v[find(1)];
for(i=2;i<=n;i++)
cout<<" "<<v[find(i)];
cout<<endl;
return 0;
}
*/
B题交互题
https://codeforces.com/contest/1167/problem/B
题目大意:6个数4, 8, 15, 16, 23, 42组成的某种组合,你可以询问系统四次,每次询问的格式为?i j
系统会回复你ai*aj的值,问你这个组合是哪种,有解且解是唯一的
解题思路:cin,cout可以自动刷新,而scanf,printf则需要手动用fflush(stdout)来刷新
会发现,这六个数两两乘积不相等,所以a1a2 a2a3这样的解是唯一的,并且只有六个数,我们用next_permatation全排列函数可以得到结果
一个从未见过的函数
https://www.cnblogs.com/eudiwffe/p/6260699.html 详见大佬的解释
代码:
#include<iostream>
#include<algorithm>
using namespace std;
int a[7]={4,8,15,16,23,42};
int main()
{
int n1,n2,n3,n4;
cout<<"? 1 2"<<endl;
cin>>n1;
cout<<"? 2 3"<<endl;
cin>>n2;
cout<<"? 4 5"<<endl;
cin>>n3;
cout<<"? 5 6"<<endl;
cin>>n4;
while(1)
{
next_permutation(a,a+6);
if(a[0]*a[1]==n1 && a[1]*a[2]==n2 && a[3]*a[4]==n3 && a[4]*a[5]==n4)
{
cout<<"! "<<a[0]<<" "<<a[1]<<" "<<a[2]<<" "<<a[3]<<" "<<a[4]<<" "<<a[5]<<endl;
break;
}
}
return 0;
}
C题贪心
http://codeforces.com/problemset/problem/1162/B
题目大意:给你两个矩阵,问你是否能通过交换对应位置的值使得两个矩阵都为严格递增矩阵
思路:依次比较两个矩阵的值,大的放在一个矩阵里,小的放在一个矩阵里
再看看是否递增
代码如下:
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int a[55][55],b[55][55];
int main()
{
int n,m,i,j,min_,max_;
cin>>n>>m;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
cin>>a[i][j];
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
cin>>b[i][j];
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
min_=min(a[i][j],b[i][j]);
max_=max(a[i][j],b[i][j]);
a[i][j]=min_;
b[i][j]=max_;
}
}
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(a[i][j]<=a[i-1][j]||a[i][j]<=a[i][j-1]||b[i][j]<=b[i-1][j]||b[i][j]<=b[i][j-1])
{
cout<<"Impossible"<<endl;
return 0;
}
}
}
cout<<"Possible"<<endl;
return 0;
}
D题 几何题、
http://codeforces.com/contest/1156/problem/A
题目大意:1代表圆,2代表三角形,3代表正方形 会给你一个序列
先出现的图形在外面,问你有多少个交点,如果有无穷多个输出Infinite,否则输出finite并输出交点个数。
解题思路:1,圆形遇三角形是3 圆形遇正方形是4
2,三角形遇圆形是 3 三角形遇正方形是重合
3,正方形遇圆形是4 正方形遇三角形重合
具体用笔一画就行
注意~!!!有一个特判:正方形 圆 三角形 会重合一个点
代码如下:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
int a[110],i,j=1,ans=0;
int n;
cin>>n;
for(i=1;i<=n;i++)
cin>>a[i];
for(i=1;i<n;i++)
{
if(a[i]==1)
{
if(a[i+1]==2)
ans+=3;
if(a[i+1]==3)
ans+=4;
}
if(a[i]==2)
{
if(a[i+1]==1)
ans+=3;
if(a[i+1]==3)
{
j=0;
cout<<"Infinite"<<endl;
break;
}
}
if(a[i]==3)
{
if(a[i+1]==1)
ans+=4;
if(a[i+1]==2)
{
j=0;
cout<<"Infinite"<<endl;
break;
}
}
if(a[i]==3&&a[i+1]==1&&a[i+2]==2)
ans--;
}
if(j)
{
cout<<"Finite"<<endl;
cout<<ans<<endl;
}
return 0;
}