zoukankan      html  css  js  c++  java
  • [ABC187] AtCoder Beginner Contest 187

    Tasks

    Task Name Time Limit Memory Limit
    A Large Digits 2 sec 1024 MB Submit
    B Gentle Pairs 2 sec 1024 MB Submit
    C 1-SAT 2 sec 1024 MB Submit
    D Choose Me 2 sec 1024 MB Submit
    E Through Path 2 sec 1024 MB Submit
    F Close Group 3 sec 1024 MB Submit

    A

    #include<bits/stdc++.h>
    
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    
    int val(int n)
    {
    	int res=0;
    	for(;n;n/=10) 
    		res+=n%10;
    	return res;
    }
    
    int main()
    {
    //	freopen("1.in","r",stdin);
    	int a,b;
    	cin>>a>>b;
    	cout<<max(val(a),val(b))<<endl;
    	return 0;
    }
    

    B

    #include<bits/stdc++.h>
    
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef pair<double,double> PDD;
    typedef PDD Point;
    
    #define x first
    #define y second
    
    int calc(Point a,Point b)
    {
    	double k=(a.y-b.y)/(a.x-b.x);
    	if(k>=-1 && k<=1) return 1;
    	else return 0;
    }
    
    const int N=1e3+5;
    
    int n;
    Point a[N];
    int ans;
    
    int main()
    {
    //	freopen("1.in","r",stdin);
    	int i,j;
    	
    	scanf("%d",&n);
    	for(i=1;i<=n;i++) 
    		scanf("%lf%lf",&a[i].x,&a[i].y);
    	
    	for(i=1;i<=n;i++) 
    		for(j=i+1;j<=n;j++) 
    			ans+=calc(a[i],a[j]);
    	
    	cout<<ans<<endl;
    	return 0;
    }
    

    讲的有内涵一点,此题是计算几何。

    没卡精度好评。

    C

    #include<bits/stdc++.h>
    
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    
    int n;
    
    set<string> mp0,mp1;
    
    void read(string &s)
    {
    	static char a[20];
    	scanf("%s",a);
    	s=a;
    }
    
    int main()
    {
    //	freopen("1.in","r",stdin);
    	int i;
    	string s;
    	
    	scanf("%d",&n);
    	for(i=1;i<=n;i++) {
    		read(s);
    //		cout<<s<<endl;
    		if(s[0]=='!') {
    			s.erase(s.begin());
    			if(mp0.count(s)) {
    				printf("%s
    ",s.c_str());
    				return 0;
    			}
    			mp1.insert(s);
    		}
    		else {
    			if(mp1.count(s)) {
    				printf("%s
    ",s.c_str());
    				return 0;
    			}
    			mp0.insert(s);
    		}
    	}
    	
    	printf("satisfiable
    ");
    	return 0;
    }
    

    D

    题意:

    AtCoder City will hold a mayoral election. The candidates are Aoki and Takahashi.
    The city consists of N towns, the i-th of which has Ai pro-Aoki voters and Bi pro-Takahashi voters. There are no other voters.
    Takahashi can make a speech in each town.
    If he makes a speech in some town, all voters in that town, pro-Takahashi or pro-Aoki, will vote for Takahashi.
    On the other hand, if he does not make a speech in some town, the pro-Aoki voters in that town will vote for Aoki, and the pro-Takahashi voters will not vote.
    To get more votes than Aoki, in how many towns does Takahashi need to make speeches at least?

    简化题意:

    给定 (n) 个点:

    • 若选第 (i) 个点, Takahashi 将会获得 (a_i+b_i) .
    • 若不选,pro-Aoki 将会获得 (a_i) .

    选择尽量少的点,使 Takahashi 获得的更多。

    思路 :

    令 Takahashi 获得的为 (sum_B) , pro-Aoki 获得的为 (sum_A).

    [sum_B>sum_A ]

    [sum_B-sum_A>0 ]

    (sum=sumB-sumA) ,考虑选和不选对 (sum) 的影响。

    不妨初始都为不选,再一个个选。

    所以 初始 (sum=sum_{i-1}^{n}-a_i)

    • 若选第 (i) 个点, (sum +=2a_i+b_i)
    • 若不选, (sum) 不变。

    选择尽量少的点使 (sum>0)

    只需一直选 (2a_i+b_i) 最大的即可。

    贪心

    Code:

    #include<bits/stdc++.h>
    
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    
    const int N=2e5+5;
    
    struct town
    {
    	LL a,b;
    	inline bool operator<(const town &t) const
    	{
    		return 2*a+b>t.a*2+t.b;
    	}
    }a[N];
    
    int n;
    LL sum;
    
    int main()
    {
    //	freopen("1.in","r",stdin);
    	int i;
    	
    	scanf("%d",&n);
    	for(i=1;i<=n;i++) {
    		scanf("%lld%lld",&a[i].a,&a[i].b);
    		sum-=a[i].a;
    	}
    		
    	sort(a+1,a+n+1);
    	for(i=1;i<=n;i++) {
    		sum+=2*a[i].a+a[i].b;
    		if(sum>0) {
    			printf("%d
    ",);
    			return 0;
    		}
    	}
    	return 0;
    }
    

    E

    dfs序+差分,裸题。

    #include<bits/stdc++.h>
    
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    
    const int N=4e5+5;
    
    int one[N],idx;
    int Next[N],ver[N];
    inline void AddEdge(int a,int b)
    {
    	Next[idx]=one[a],ver[idx]=b,one[a]=idx++;
    	Next[idx]=one[b],ver[idx]=a,one[b]=idx++;
    }
    
    struct Edge
    {
    	int a,b;
    }e[N];
    
    int dfn[N],dfnt[N],times;
    int dep[N];
    
    void dfs(int x,int fa)
    {
    	dfn[x]=++times;
    	dep[x]=dep[fa]+1;
    	for(int i=one[x],y;~i;i=Next[i]) {
    		y=ver[i];
    		if(y==fa) continue;
    		dfs(y,x);
    	}
    	dfnt[x]=times;
    }
    
    int n,m;
    LL c[N];
    
    int main()
    {
    //	freopen("1.in","r",stdin);
    	int i;
    	int opt,x,y,id;
    	LL z;
    	
    	scanf("%d",&n);
    	memset(one,-1,sizeof one);
    	for(i=1;i<=n-1;i++) {
    		scanf("%d%d",&e[i].a,&e[i].b);
    		AddEdge(e[i].a,e[i].b);
    	}
    	
    	dfs(1,0);
    	
    	scanf("%d",&m);
    	while(m--) {
    		scanf("%d%d%lld",&opt,&id,&z);
    		if(opt==1) {
    			x=e[id].a,y=e[id].b;
    			if(dep[x]>dep[y]) {
    				c[dfn[x]]+=z;
    				c[dfnt[x]+1]-=z;
    			}
    			else {
    				c[1]+=z;
    				c[dfn[y]]-=z;
    				c[dfnt[y]+1]+=z;
    				c[n+1]-=z;
    			}
    		}
    		
    		else {
    			x=e[id].a,y=e[id].b;
    			if(dep[y]>dep[x]) {
    				c[dfn[y]]+=z;
    				c[dfnt[y]+1]-=z;
    			}
    			else {
    				c[1]+=z;
    				c[dfn[x]]-=z;
    				c[dfnt[x]+1]+=z;
    				c[n+1]-=z;
    			}
    		}
    	}
    	
    	for(i=1;i<=n;i++) c[i]+=c[i-1];
    	for(i=1;i<=n;i++)
    		printf("%lld
    ",c[dfn[i]]);
    	return 0;
    }
    

    时间复杂度:(O(n))

    空间复杂度:(O(n))

    F

    Problem Statement

    Given is a simple undirected graph with N vertices and M edges. The vertices are numbered 1,2,…,N, and the i-th edge connects Vertices Ai and Bi.

    Find the minimum possible number of connected components in the graph after removing zero or more edges so that the following condition will be satisfied:

    Condition:
    For every pair of vertices (a,b)such that 1≤a<b≤N, if Vertices a and b belong to the same connected component, there is an edge that directly connects Vertices a and b.

    Constraints

    • All values in input are integers.
    • 1≤N≤18
    • 0≤M≤N(N−1)/2
    • 1≤Ai<Bi≤N
    • (Ai,Bi)≠(Aj,Bj) for i≠j.

    题意:删边,保留尽量少的联通块,使 所有极大联通子图都为完全图。

    一看 (n leq 18) ,是状压没得跑了。

    先遍历一遍,哪些子图可行,然后子集枚举即可。

    #include<bits/stdc++.h>
    
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    
    const int N=19,S=(1<<19)+5;
    int n,m;
    bool w[N][N];
    int f[S];
    
    int main()
    {
    //	freopen("1.in","r",stdin);
    	int i,j,k;
    	int x,y;
    	
    	scanf("%d%d",&n,&m);
    	for(i=1;i<=m;i++) {
    		scanf("%d%d",&x,&y);
    		x--,y--;
    		w[x][y]=w[y][x]=true;
    	}
    	
    	memset(f,0x3f,sizeof f);
    	for(i=0;i<(1<<n);i++) {
    		for(j=0;j<n;j++) {
    			if(!((i>>j)&1)) continue;
    			for(k=j+1;k<n;k++) {
    				if(!((i>>k)&1)) continue;
    				if(!w[j][k]) break;
    			}
    			if(k<n) break;
    		}
    		if(j==n) f[i]=1;
    	}
    	
    	for(i=0;i<(1<<n);i++) 
    		for(j=(i-1)&i;j;j=(j-1)&i) 
    			f[i]=min(f[i],f[j]+f[i-j]);
    	
    	printf("%d
    ",f[(1<<n)-1]);
    	return 0;
    }
    

    时间复杂度:(O(n^22^n+3^n)) ,这 AtCoder 神机。

    附:此题好像没法把一个一个点加入状态,因为如果要的话,还要维护状态内部的联通性信息,难以做到,所以只能一次把一个可行集合都加进来。

    类似的题:

    1118 分成互质组
    524 愤怒的小鸟 (需优化)(可限定当前点的最小编号为更新后的最小编号 或 仅使用 bfs。

    完结撒花

    第二次 AK ABC.

  • 相关阅读:
    Leetcode 449. Serialize and Deserialize BST
    机器学习入门(1)------python基础
    Leetcode 23. Merge k Sorted Lists
    mysql explain执行计划详解
    ubuntu下安装chrome浏览器证书
    ubantu下配置android开发环境(Ubuntu 12.04.4 LTS x64 dell 3420)
    system v信号量的深入剖析
    AI文件格式解析
    STC12LE5A60S2第二串口出现的奇葩问题
    ZIGBEE官方协议栈 SampleApp工程DemoEB项目 运行机制详解
  • 原文地址:https://www.cnblogs.com/cjl-world/p/14224193.html
Copyright © 2011-2022 走看看