zoukankan      html  css  js  c++  java
  • CF1082解题报告

    CF1082A Vasya and Book

    模拟一下即可

    (Code Below:)

    #include <bits/stdc++.h>
    using namespace std;
    const int inf=0x3f3f3f3f;
    int n,x,y,d,ans;
    
    int main()
    {
    	int T;
    	scanf("%d",&T);
    	while(T--){
    		scanf("%d%d%d%d",&n,&x,&y,&d);
    		if((x-y)%d==0) printf("%d
    ",abs(x-y)/d);
    		else {
    			ans=inf;
    			if(y%d==1) ans=min(ans,(x-1)/d+y/d+1);
    			if((n-y)%d==0) ans=min(ans,(n-x-1)/d+(n-y)/d+1);
    			printf("%d
    ",(ans==inf)?-1:ans);
    		}
    	}	
    	return 0;
    }
    

    CF1082B Vova and Trophies

    (WA) 了一次。。。

    把所有的连续金牌都预处理出来,然后特判一下即可

    (Code Below:)

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=100000+10;
    int n,st[maxn],ed[maxn],cnt,ans;
    char a[maxn];
    
    int main()
    {
    	scanf("%d%s",&n,a+1);
    	int now=0;
    	for(int i=1;i<=n+1;i++){
    		if(a[i]=='G'){
    			if(now==0) st[++cnt]=i;
    			now++;
    		}
    		else if(now) ed[cnt]=st[cnt]+now-1,now=0;
    	}
    	if(cnt==0) ans=0;
    	else if(cnt==1) ans=ed[1]-st[1]+1;
    	else {
    		for(int i=1;i<=cnt;i++){
    			ans=max(ans,ed[i]-st[i]+2);
    			if(i>1&&ed[i-1]+2==st[i]){
    				if(cnt==2) ans=max(ans,ed[i]-st[i-1]);
    				else ans=max(ans,ed[i]-st[i-1]+1);
    			}
    		}
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    

    CF1082C Multi-Subject Competition

    贪心,若 (>0) 便算进前缀和中

    (Code Below:)

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=100000+10;
    int n,m,s[maxn],r[maxn],sum[maxn],ans;
    vector<int> v[maxn];
    
    bool cmp(int a,int b){
    	return a>b;
    }
    
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++){
    		scanf("%d%d",&s[i],&r[i]);
    		v[s[i]].push_back(r[i]);
    	}
    	for(int i=1;i<=m;i++)
    		sort(v[i].begin(),v[i].end(),cmp);
    	int now;
    	for(int i=1;i<=m;i++){
    		now=0;
    		for(int j=0;j<v[i].size();j++){
    			now+=v[i][j];
    			if(now>0) sum[j+1]+=now;
    			else break;
    		}
    	}
    	for(int i=1;i<=n;i++)
    		ans=max(ans,sum[i]);
    	printf("%d
    ",ans);
    	return 0;
    }
    

    CF1082D Maximum Diameter Graph

    (CF) 考构造题。。。

    先按度数排序,然后从后往前扫,贪心找最长的直径

    (Code Below:)

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1000+10;
    int n,m,x[maxn],y[maxn],tot;
    
    struct Element{
    	int val,id;
    }e[maxn];
    
    bool cmp(Element a,Element b){
    	return a.val<b.val;
    }
    
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++){
    		scanf("%d",&e[i].val);
    		e[i].id=i;
    	}
    	sort(e+1,e+n+1,cmp);
    	int st=-1,pos,id;
    	for(int i=1;i<=n;i++){
    		if(e[i+1].val>1){
    			st=i;
    			break;
    		}
    	}
    	if(st==-1){
    		printf("NO
    ");
    		return 0;
    	}
    	for(int i=st;i<=n-1;i++){
    		x[++tot]=e[i].id;
    		y[tot]=e[i+1].id;
    		e[i].val--;e[i+1].val--;
    	}
    	pos=st-1;
    	for(int i=n;i>=st;i--){
    		id=e[i].id;
    		while(e[i].val&&pos){
    			x[++tot]=e[i].id;
    			y[tot]=e[pos].id;
    			e[i].val--;e[pos].val--;
    			pos--;
    		}
    		if(pos==0) break;
    	}
    	if(pos>0||tot!=n-1) printf("NO
    ");
    	else {
    		printf("YES %d
    %d
    ",min(n-1,n-st+1),tot);
    		for(int i=1;i<=tot;i++)
    			printf("%d %d
    ",x[i],y[i]);
    	}
    	return 0;
    }
    

    CF1082E Increasing Frequency

    想了半天数据结构,结果居然是 (O(n)) 的解法。。。

    问题等价于找一个区间 ([l,r]),使整个序列 (c) 出现的次数+区间 ([l,r]) 中出现最多的数的出现次数-区间 ([l,r])(c) 出现的次数,然后 (c) 出现的次数可以直接前缀和 (O(1)) 算出,剩下的用最大子段和的思路 (O(n)) 扫一遍即可

    (Code Below:)

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=500000+10;
    int n,m,c,a[maxn],sum[maxn],last[maxn],ans;
    vector<int> v[maxn];
    
    int main()
    {
    	scanf("%d%d",&n,&c);
    	for(int i=1;i<=n;i++){
    		scanf("%d",&a[i]);
    		m=max(m,a[i]);
    		sum[i]=sum[i-1]+(a[i]==c);
    		if(!last[a[i]]) v[a[i]].push_back(1);
    		else v[a[i]].push_back(1-(sum[i]-sum[last[a[i]]]));
    		last[a[i]]=i;
    	}
    	ans=sum[n];
    	int now=0,num=0;
    	for(int i=1;i<=m;i++){
    		if(i==c) continue;
    		now=0;
    		for(int j=0;j<v[i].size();j++){
    			now+=v[i][j];
    			num=max(num,now);
    			if(now<=0) now=1;
    		}
    	}
    	printf("%d
    ",ans+num);
    	return 0;
    }
    

    CF1082F Speed Dial

    占坑中

    CF1082G Petya and Graph

    最大权闭合子图,同 ([NOI2006]) 最大获利。

    因为选了边权一定会选点权,满足最大权闭合子图的性质。我们建一个超级源和超级汇,左边 (m) 个数表示 (m) 条边,超级源向其连容量为边权的边;右边 (n) 个数表示 (n) 个点,其向超级汇连容量为点权的边.然后原图中每条边向其两个端点连 (inf) 的边,表示选了边权必须选点权,最小割不可能将其割掉。又因为最小割等于最大流,所以最后的答案为 (sum_{i=1}^{m} val_i-maxflow)

    (Code Below:)

    #include <bits/stdc++.h>
    #define int long long
    using namespace std;
    const int maxn=400000+10;
    const int inf=0x3f3f3f3f;
    int n,m,s,t,head[maxn],tot=1;
    int dep[maxn],cur[maxn];
    
    struct node{
    	int to,next,val;
    }e[maxn];
    
    inline void add(int x,int y,int w){
    	e[++tot].to=y;e[tot].val=w;
    	e[tot].next=head[x];head[x]=tot;
    	e[++tot].to=x;e[tot].val=0;
    	e[tot].next=head[y];head[y]=tot;
    }
    
    int bfs(int s,int t){
    	queue<int> q;
    	for(int i=0;i<=t;i++)
    		cur[i]=head[i];
    	memset(dep,0x7f,sizeof(dep));
    	dep[s]=0;q.push(s);
    	int u,v;
    	while(!q.empty()){
    		u=q.front(),q.pop();
    		for(int i=head[u];i;i=e[i].next){
    			v=e[i].to;
    			if(dep[v]>inf&&e[i].val){
    				dep[v]=dep[u]+1;
    				q.push(v);
    			}
    		}
    	}
    	return dep[t]<inf;
    }
    
    int dfs(int now,int t,int limit){
    	if(!limit||now==t) return limit;
    	int flow=0,f,v;
    	for(int i=cur[now];i;i=e[i].next){
    		cur[now]=i;v=e[i].to;
    		if(dep[v]==dep[now]+1&&(f=dfs(v,t,min(limit,e[i].val)))){
    			flow+=f;
    			limit-=f;
    			e[i].val-=f;
    			e[i^1].val+=f;
    			if(!limit) break;
    		}
    	}
    	return flow;
    }
    
    int Dinic(){
    	int maxflow=0;
    	while(bfs(s,t))
    		maxflow+=dfs(s,t,inf);
    	return maxflow;
    }
    
    signed main()
    {
    	scanf("%I64d%I64d",&n,&m);
    	s=0;t=n+m+1;
    	int p,a,b,c,sum=0;
    	for(int i=1;i<=n;i++){
    		scanf("%I64d",&p);
    		add(i+m,t,p);
    	}
    	for(int i=1;i<=m;i++){
    		scanf("%I64d%I64d%I64d",&a,&b,&c);
    		sum+=c;add(s,i,c);
    		add(i,a+m,inf);add(i,b+m,inf);
    	}
    	printf("%I64d
    ",sum-Dinic());
    	return 0;
    }
    
  • 相关阅读:
    TinyOS功率编程指南
    深度学习入门资料
    通信常识
    CTF入门
    前端开发工具之服务器选择
    Spring
    NoSQL -- MongoDB
    NoSQL -- Redis
    mysql alter table修改表结构添加多个字段的几个写法
    gongle 访问助手安装
  • 原文地址:https://www.cnblogs.com/owencodeisking/p/10125677.html
Copyright © 2011-2022 走看看