CodeForces Gym 101669

C

Christmas Tree

待补...

D

Harry Potter and The Vector Spell

题意:给出一个n行m列的仅含有数字0 1的矩阵,求矩阵的秩,注意题目中有句话:每列为1的元素只有两个

分析:并查集思想,用vector存好图后,遍历每列,把1所在的点用边连起来,最后数有几条边就好

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
int N,M;
vector<int>vec[maxn]; 
int pre[maxn];
int num[maxn];//集合内元素个数 
void init2(){
	for(int i=1;i<=N;++i){
		int k;
		cin>>k;
		for(int j=1;j<=k;++j){
			int ci;
			cin>>ci;
			vec[ci].push_back(i);//i是行,ci是列,注意不要弄混了 
		}
	}
}
void init1(){
	for(int i=0;i<=N;++i){
		num[i]=1;
		pre[i]=i;
	}
}
int find(int x){
	if(x==pre[x])
		return x;
	return pre[x]=find(pre[x]);
}
void join(int x,int y){
	int fx=find(x);
	int fy=find(y);
	
	if(fx==fy)return;
	pre[fy]=fx;		//fx是fy的祖先 
	num[fx]+=num[fy];
}
int main()
{
	ios::sync_with_stdio(false);
	cin>>N>>M;
	init1(); 
	init2();
	
	for(int i=1;i<=M;i++){//按列遍历 ,题目中说了每行只有两个数非0 
		int x=vec[i][0];
		int y=vec[i][1];
		join(x,y);
	}
	
	int ans=0;
	for(int i=1;i<=N;i++) {
		if(find(i)==i){
			ans+=(num[i]-1);//由于num存的是点的个数,边数=点数-1 
		}
	}
	cout<<ans<<endl;
    return 0; 
}
F

Binary Transformations

待补... 

K

Escape Room

题意:第一行给出了一个数字n,表示序列从1-n,接下来n个数表示从某个数开始的最长上升子序列个数,还原原序列 

分析:思维题,只要用笔多列出几组数据就能知道,从左向右的第一个1一定是最大的,第二个1是次大的...以此类推...所以我们只需要开一个vector数组记录它们的位置即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=1e7+5;
const int maxn=1e5+5;
const int mod=1e9+7;
int N;
int a[maxn];
vector<int>vec[maxn];
int ans[maxn];
int main()
{
   	ios::sync_with_stdio(false);
   	cin>>N;
   	for(int i=1;i<=N;i++){
   		cin>>a[i];
   		vec[a[i]].push_back(i);
   	}
   	bool flag=0;
   	int t=N;
   	for(int i=1;i<=N;i++){
   		for(int j=0;j<vec[i].size();j++){
   			if(t==0){
   				flag=1;
   				break;
   			}
   			ans[vec[i][j]]=t;
   			t--;
   		}
   		if(flag)break;
   	}
   	
   	for(int i=1;i<=N;i++){
   		cout<<ans[i]<<' ';
   	}
    return 0;
}
G

Robots

签到题

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=1e7+5;
const int maxn=1e5+5;
const int mod=1e9+7;
struct Node{
	double a,t;
}p[maxn];
int N;
bool cmp(Node x,Node y){
	return x.a>y.a;
}
int main()
{
   	ios::sync_with_stdio(false);
   	cin>>N;
   	for(int i=1;i<=N;i++){
   		cin>>p[i].a>>p[i].t;
   	}
   	double x1=0;
   	double v=0;
   	double v0=0;
   	for(int i=1;i<=N;i++){
   		x1+=v0*p[i].t+(0.5)*p[i].a*p[i].t*p[i].t;
   		v=v0+p[i].a*p[i].t;
   		v0=v;
   	}
   	
   	sort(p+1,p+1+N,cmp);
   	
   	double x2=0;
   	v=0;v0=0;
   	for(int i=1;i<=N;i++){
   		x2+=v0*p[i].t+(0.5)*p[i].a*p[i].t*p[i].t;
   		v=v0+p[i].a*p[i].t;
   		v0=v;
   	}
 //  	cout<<x2<<endl;
   	printf("%.1f\n",abs(x1-x2));
    return 0;
}
J

Cunning Friends

题意:n堆石头,每堆ai个,两个人A,B轮流取非0数目的石头,其中B必须连续取两次,问先手能否赢

分析:emmmm,我也是看的别人的题解......先放着吧

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
int N;
int one,two,x;
int main()
{
	ios::sync_with_stdio(false);
	cin>>N;
	for(int i=1;i<=N;i++){
		int ai;
		cin>>ai;
		if(ai==1)one++;
		else if(ai==2)two++;
		else x++;
	} 
	if(N%3==0){
		if(one==N-1)
			cout<<"Win"<<endl;
		else if(one==N-2&&two!=0)
			cout<<"Win"<<endl;
		else
			cout<<"Lose"<<endl;
		return 0;
	}
	if(N%3==1){
		if(one==N)
			cout<<"Win"<<endl;
		else if(one==N-1)
			cout<<"Win"<<endl;
		else if(one==N-2&&two!=0)
			cout<<"Win"<<endl;
		else
			cout<<"Lose"<<endl;
		return 0;
	}
	if(N%3==2){
		if(one==N)
			cout<<"Win"<<endl;
		else if(one==N-1)
			cout<<"Win"<<endl;
		else
			cout<<"Lose"<<endl;
	} 
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zsnowwolfy/article/details/89762143