Codeforces Round #547 (Div. 3) A(分解质因数)B(思维)C(规律)D(简单模拟)E(简单模拟)F1,F2(大胆暴力)G(贪心)

A - Game 23(分解质因数)

题目链接:https://codeforces.com/contest/1141/problem/A

题目大意:给出两个数a,b,通过*2||*3的操作能否让a变成b,如果可以,输出最小的变化次数。不行就输出-1

思路:判断b是否是a的倍数,然后看倍数是否能分解成只有2和3即可。

ACCode:

//#pragma comment(linker, "/STACK:1024000000,1024000000")
  
#include<stdio.h>
#include<string.h> 
#include<math.h> 
   
#include<map>  
#include<set>
#include<deque> 
#include<queue> 
#include<stack> 
#include<bitset>
#include<string> 
#include<fstream>
#include<iostream> 
#include<algorithm> 
using namespace std; 
  
#define ll long long 
#define Pair pair<ll,ll>
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// ??
//std::ios::sync_with_stdio(false);
//  register
const int MAXN=2e5+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll mod=1e9+7;
const double PI=acos(-1.0);
const double EPS=1.0e-8;

ll GCD(ll a,ll b){
	if(b==0) return a;
	return GCD(b,a%b);
}
int main(){
	ll a,b;
	while(cin>>a>>b){
		if(a<b) swap(a,b);
		if(a%b!=0){
			cout<<-1<<endl;
			continue;
		}ll res=a/b;int flag=0;
		ll ans=0;
//		cout<<res<<endl;
		while(res%3==0){
			res/=3;ans++;
//			cout<<res<<endl;
		}
		while(res%2==0){
			res/=2;ans++;
//			cout<<res<<endl;
		}
		if(res==1) cout<<ans<<endl;
		else cout<<-1<<endl;
	}
	
}

B. Maximal Continuous Rest(思维)

题目链接:https://codeforces.com/contest/1141/problem/C

题目大意:给出一个01序列。序列可以无限重复判断最长的连续是1的长度。

思路:首位拼接到一起,然后遍历即可。

ACCode:

//#pragma comment(linker, "/STACK:1024000000,1024000000")
  
#include<stdio.h>
#include<string.h> 
#include<math.h> 
   
#include<map>  
#include<set>
#include<deque> 
#include<queue> 
#include<stack> 
#include<bitset>
#include<string> 
#include<fstream>
#include<iostream> 
#include<algorithm> 
using namespace std; 
  
#define ll long long 
#define Pair pair<int,ll>
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))
//std::ios::sync_with_stdio(false);
//  register
const int MAXN=2e5+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll mod=1e9+7;
const double EPS=1.0e-8;
const double PI=acos(-1.0);

int a[MAXN<<1];
int n;

int main(){
	while(~scanf("%d",&n)){
		for(int i=1;i<=n;++i){
			scanf("%d",&a[i]);
		}int N=n*2;
		for(int i=n+1;i<=N;++i){
			a[i]=a[i-n];
		}ll ans=0,res=0;
		for(int i=1;i<=N;++i){
			if(a[i]){
				++res;
			}
			else{
				res=0;
			}
			ans=max(ans,res);
		}printf("%lld\n",ans);
	}
}

C. Polycarp Restores Permutation(规律)

题目链接:https://codeforces.com/contest/1141/problem/C

题目大意:给出n-1个数,每个数q[i]=a[i+1]-a[i],求a数组。

思路:首先规定a1为1.然后后面的就按照给定数组的加法得出。最后所有的数都加上最小的那个数到1的差即可。注意一下边界判断。其实这题的边界不注意还真容易出错(被hack惨了)

ACCode:

//#pragma comment(linker, "/STACK:1024000000,1024000000")
  
#include<stdio.h>
#include<string.h> 
#include<math.h> 
   
#include<map>  
#include<set>
#include<deque> 
#include<queue> 
#include<stack> 
#include<bitset>
#include<string> 
#include<fstream>
#include<iostream> 
#include<algorithm> 
using namespace std; 
  
#define ll long long 
#define Pair pair<ll,ll>
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// ??
//std::ios::sync_with_stdio(false);
//  register
const int MAXN=2e5+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll mod=1e9+7;
const double PI=acos(-1.0);
const double EPS=1.0e-8;

int a[MAXN],b[MAXN];
int Vis[MAXN];
int n;

int main(){
	while(~scanf("%d",&n)){
		clean(Vis,0);
		for(int i=1;i<n;++i){
			scanf("%d",&a[i]);
		}b[1]=1;int minn=1;
		for(int i=2;i<=n;++i){
			b[i]=b[i-1]+a[i-1];
			minn=min(minn,b[i]);
		}int res=1-minn,flag=1;
		for(int i=1;i<=n;++i){
			b[i]+=res;
			if(b[i]>n||b[i]<0){
				flag=0;
			}
			else if(b[i]<=n){
				Vis[b[i]]++;
				if(Vis[b[i]]>1){
					flag=0;
				}
			}
		}
//		for(int i=1;i<=n;++i){
//			cout<<Vis[b[i]]<<" ";
//		}cout<<endl;
		if(flag==0) printf("-1\n");
		else{
			printf("%d",b[1]);
			for(int i=2;i<=n;++i) printf(" %d",b[i]);
			printf("\n");
		}
	}
}

D. Colored Boots(简单模拟)

题目链接:https://codeforces.com/contest/1141/problem/D

题目大意:2*n只鞋子,只有相同字符的上下两个才能构成一对鞋子,?的可以和另一对任意的一只构成一双鞋子。问给定2*n个字符串,最多共有多少对鞋子。

思路:因为只有26+1个字符,直接就开个vector来存对应的位置。然后上下两个,开始匹配。最后贪心匹配?的。

其实这道题我就是迷迷糊糊过的,竟然还没有被hack掉(其实当时能够AC都觉得的惊奇)。

ACCode:

//#pragma comment(linker, "/STACK:1024000000,1024000000")
  
#include<stdio.h>
#include<string.h> 
#include<math.h> 
   
#include<map>  
#include<set>
#include<deque> 
#include<queue> 
#include<stack> 
#include<bitset>
#include<string> 
#include<fstream>
#include<iostream> 
#include<algorithm> 
using namespace std; 
  
#define ll long long 
#define Pair pair<int,ll>
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))
//std::ios::sync_with_stdio(false);
//  register
const int MAXN=2e5+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll mod=1e9+7;
const double EPS=1.0e-8;
const double PI=acos(-1.0);

char s1[MAXN],s2[MAXN];
int Vis[MAXN][2];
vector<int> vec1[40],vec2[40];
int n;

int main(){
	while(cin>>n){
		clean(Vis,0);
		for(int i=0;i<40;++i){
			vec1[i].clear();vec2[i].clear();
		}clean(s1,'\0');clean(s2,'\0');
		cin>>s1>>s2;
		for(int i=0;i<n;++i){
			if(s1[i]!='?') vec1[s1[i]-'a'].insert(vec1[s1[i]-'a'].end(),i);
			else vec1[30].insert(vec1[30].end(),i);
			if(s2[i]!='?') vec2[s2[i]-'a'].insert(vec2[s2[i]-'a'].end(),i);
			else vec2[30].insert(vec2[30].end(),i);
		}int res=0;
//		for(int i=0;i<=26;++i){
//			cout<<vec1[i].size()<<" "<<vec2[i].size()<<endl;
//		}cout<<vec1[30].size()<<" "<<vec2[30].size()<<endl;
		for(int i=0;i<=26;++i){
			res+=min(vec1[i].size(),vec2[i].size());//res˫ 
		}int sum=n-res;//ʣ��sum*2ֻ 
		if(vec1[30].size()+vec2[30].size()>=sum){
			res=n;
		}
		else{
			res+=vec1[30].size()+vec2[30].size();
		}cout<<res<<endl;
		for(int i=0;i<=26;++i){//�����ַ� 
			int len=min(vec1[i].size(),vec2[i].size());
			for(int j=0;j<len;++j){
				cout<<vec1[i][j]+1<<" "<<vec2[i][j]+1<<endl;
				Vis[vec1[i][j]][0]=1;Vis[vec2[i][j]][1]=1;
			}
		}int len=vec1[30].size();
		for(int i=0,j=0;i<len&&j<n;++i){//�����һ�����ģ� 
			while(Vis[j][1]==1||s2[j]=='?'){
				++j;
			}
			if(j>=n) break;
			cout<<vec1[30][i]+1<<" "<<j+1<<endl;
			Vis[j][1]=1;Vis[vec1[30][i]][0]=1;
		}len=vec2[30].size();
		for(int i=0,j=0;i<len&&j<n;++i){
			while(Vis[j][0]==1){
				++j;
			}
			if(j>=n) break;
			cout<<j+1<<" "<<vec2[30][i]+1<<endl;
			Vis[j][0]=1;Vis[vec2[30][i]][1]=1;
		}
	}
}

E. Superhero Battle(简单模拟)

题目链接:https://codeforces.com/contest/1141/problem/E

题目大意:一个怪物,一开始有H滴血,在剩下的n个时间内,血量会发生变化,每次增加||减少a[i]滴血。怪物的血量一直循环。问怪物会死不会,如果死亡,输出在那回合死亡的。不死亡输出-1

思路:模拟,没什么难的。

ACCode:

//#pragma comment(linker, "/STACK:1024000000,1024000000")
  
#include<stdio.h>
#include<string.h> 
#include<math.h> 
   
#include<map>  
#include<set>
#include<deque> 
#include<queue> 
#include<stack> 
#include<bitset>
#include<string> 
#include<fstream>
#include<iostream> 
#include<algorithm> 
using namespace std; 
  
#define ll long long 
#define Pair pair<ll,ll>
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// ??
//std::ios::sync_with_stdio(false);
//  register
const int MAXN=2e5+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll mod=1e9+7;
const double PI=acos(-1.0);
const double EPS=1.0e-8;

ll a[MAXN],sum[MAXN];
ll Hp,n;

int main(){
//	while(~){
	scanf("%lld%lld",&Hp,&n);
		ll minn=INF64;sum[0]=0;
		for(int i=1;i<=n;++i){
			scanf("%lld",&a[i]);
			sum[i]=sum[i-1]+a[i];
			minn=min(minn,sum[i]);
		}
		if(Hp+minn<=0){//��һ�ֻ�ɱ 
			for(int i=1;i<=n;++i){
				if(Hp+sum[i]<=0){
					printf("%d\n",i);
					break;
				}
			}
		}
		else if(sum[n]>=0){//��Զ����ɱ�� 
			printf("-1\n");
		}
		else{//�ظ���ɱ 
			ll res=abs(Hp/sum[n]),sur=abs(Hp%sum[n]);//����������ʣ��Ѫ�� 
//			cout<<res<<" "<<sur<<endl;
			while(sur+minn<=0){//���һ�ֿ���ֱ��ɱ�� 
//				cout<<sur<<" "<<minn<<endl;
				sur-=sum[n];
				res--;
			}sur+=sum[n];res++;
//			cout<<sur<<" "<<res<<endl;
			ll ans=res*n;
			for(int i=1;i<=n;++i){
				if(sur+sum[i]<=0){
					ans+=i;
					break;
				}
			}
			printf("%lld\n",ans);
		}
//	}
}

F1,F2. Same Sum Blocks (大胆暴力)

题目链接:F1:https://codeforces.com/contest/1141/problem/F1   F2:https://codeforces.com/contest/1141/problem/F2

题目大意:给n个数,问最多有多少个区间的数(一个区间内所有的数之和)相等。输出最大的那个区间个数。

思路:暴力!标称就是暴力,枚举所有区间,然后遍历就行了。人尽皆知**题?

ACCode:

//#pragma comment(linker, "/STACK:1024000000,1024000000")
  
#include<stdio.h>
#include<string.h> 
#include<math.h> 
   
#include<map>  
#include<set>
#include<deque> 
#include<queue> 
#include<stack> 
#include<bitset>
#include<string> 
#include<fstream>
#include<iostream> 
#include<algorithm> 
using namespace std; 
  
#define ll long long 
#define Pair pair<int,int>
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// ??
//std::ios::sync_with_stdio(false);
//  register
const int MAXN=3e6+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll mod=1e9+7;
const double PI=acos(-1.0);
const double EPS=1.0e-8;

pair<ll,Pair> part[MAXN];
int a[MAXN];
int n;

int Cmp(pair<ll,Pair> a,pair<ll,Pair> b){
	if(a.first==b.first){
		return a.second.second<b.second.second;//��������ķ�ǰ�� 
	}
	return a.first<b.first;
}
int main(){
	while(~scanf("%d",&n)){
		for(int i=1;i<=n;++i){
			scanf("%d",&a[i]);
		}int ecnt=0;
		for(int i=1;i<=n;++i){
			ll sum=0;
			for(int j=i;j<=n;++j){
				sum+=a[j];
				part[ecnt++]=make_pair(sum,make_pair(i,j));
			}
		}sort(part,part+ecnt,Cmp);
		int ans=1,res=1,ansnum=part[0].first,last=part[0].second.second;
		for(int i=1;i<ecnt;++i){
			if(part[i].first==part[i-1].first){//��ͬ�Ĵ� 
				if(part[i].second.first>last){//���䲻��ͻ 
					res++;last=part[i].second.second;//�ɹ�ѡ������+1 
				}
			}
			else{//����һ����ͬ 
				res=1;last=part[i].second.second;
			}
//			printf("now num is %d,res is %d,part is l=%d r=%d\n",part[i].first,res,part[i].second.first,part[i].second.second);
			if(ans<res){
				
				ans=res;ansnum=part[i].first;
//				cout<<ansnum<<" "<<ans<<endl;
			}
		}printf("%d\n",ans);
		int flag=0;
//		cout<<ansnum<<endl;
//		for(int i=0;i<ecnt;++i){
//			printf("%d : %d %d\n",part[i].first,part[i].second.first,part[i].second.second);
//		}
		for(int i=0;i<ecnt;++i){
			if(part[i].first==ansnum){
				printf("%d %d\n",part[i].second.first,part[i].second.second);
				last=part[i].second.second;
				for(int j=i+1;j<ecnt;++j){
					if(part[j].first!=ansnum) break;
					if(part[j].second.first>last){
						printf("%d %d\n",part[j].second.first,part[j].second.second);
						last=part[j].second.second;
					}
				}flag=1;
			}
			if(flag) break;
		}
	}
}

G. Privatization of Roads in Treeland(贪心)

题目链接:https://codeforces.com/contest/1141/problem/G

题目大意:一些城市之间有道路相连,连成的结果就是一棵树(题目说明)。每个城市之间的道路可以被染成一种颜色。可以接受最多k个道路的颜色相邻&&相连。问最少需要多少种颜色符合要求的染完所有的道路。

思路:表面上染色问题,其实我们只需要优先将度数多的点的相邻的道路染成同一种颜色。这样其他的就不用考虑那么多冲突了。度数少的点,所用到的颜色只会越来越少。

ACCode:

//#pragma comment(linker, "/STACK:1024000000,1024000000")
  
#include<stdio.h>
#include<string.h> 
#include<math.h> 
   
#include<map>  
#include<set>
#include<deque> 
#include<queue> 
#include<stack> 
#include<bitset>
#include<string> 
#include<fstream>
#include<iostream> 
#include<algorithm> 
using namespace std; 
  
#define ll long long 
#define Pair pair<int,int>
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// ??
//std::ios::sync_with_stdio(false);
//  register
const int MAXN=2e5+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll mod=1e9+7;
const double PI=acos(-1.0);
const double EPS=1.0e-8;

struct node{
	int v,nxt,val;
	node(int _v=0,int _val=0,int _nxt=0){
		v=_v;val=_val;nxt=_nxt;
	}
}Edge[MAXN<<1];
int Head[MAXN],Ecnt;
int Degree[MAXN],Ans[MAXN];
int n,m,k;

void Intt(){
	clean(Degree,0);
	clean(Head,-1);
	Ecnt=0;
}
void Add(int u,int v,int val){
	Edge[Ecnt]=node(v,val,Head[u]);
	Head[u]=Ecnt++;
}
void DFS(int u,int fa,int color){
	for(int i=Head[u];i+1;i=Edge[i].nxt){
		int temp=Edge[i].v;
		if(temp==fa) continue;
		if(color>m) color-=m;
		Ans[Edge[i].val]=color++;
		DFS(temp,u,color);
	}
}
int Cmp(int a,int b){
	return a>b;
}
int main(){
	while(~scanf("%d%d",&n,&k)){
		int a,b;Intt();
		for(int i=1;i<n;++i){
			scanf("%d%d",&a,&b);
			++Degree[a];++Degree[b];
			Add(a,b,i);Add(b,a,i);
		}sort(Degree+1,Degree+1+n,Cmp);//???n???? 
		m=Degree[k+1];DFS(1,0,1);
		printf("%d\n",m);
		for(int i=1;i<n;++i){
			printf("%d ",Ans[i]);
		}
	}
}

猜你喜欢

转载自blog.csdn.net/qq_40482358/article/details/88795120
今日推荐