zoukankan      html  css  js  c++  java
  • 【Codeforces #142 Div2】Solutions

      先发Div2的吧,Div1的要看能搞定多少……(一般不全搞出来是不会写题解的……)

    【A. Dragons】

      http://www.codeforces.com/contest/230/problem/A

      题目大意:有个人打怪兽,自己和怪兽都有一个属性,属性高的能战胜低的,打败一个怪兽能获得额外属性。问能否全胜通关。

      从小到大打就是了……没什么意思……

    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    int s,n;
    struct REC{int x,y;}a[1010];
    
    bool cmp(REC a,REC b){
    	return a.x<b.x;
    }
    
    int main(){
    	cin>>s>>n;
    	for(int i=1;i<=n;i++)
    		cin>>a[i].x>>a[i].y;
    	sort(a+1,a+1+n,cmp);
    	for(int i=1;i<=n;i++){
    		if(s<=a[i].x){
    			cout<<"NO"<<endl;
    			return 0;
    		}
    		s+=a[i].y;
    	}
    	cout<<"YES"<<endl;
    }
    

    【B. T-primes】

      http://www.codeforces.com/contest/230/problem/B

      题目大意:给定一堆数,判断他们每个是不是T-prime,T-prime数定义为该数有且仅有三个质因子。

      任何一个数都有1和它本身俩质因子。还剩一个……是啥呢?只有sqrt(n)。因为如果不是它的话,必然会产生偶数个质因子。

      比较坑人,也没什么意思……

    #include <iostream>
    #include <cmath>
    #define sqr(x) ((x)*(x))
    using namespace std;
    
    bool composite[1000010];
    int n;
    long long x;
    
    int main(){
    	composite[1]=true;
    	for(int i=2;i<=1000000;i++)
    		if(!composite[i]){
    			for(int j=2;i*j<=1000000;j++)
    				composite[i*j]=true;
    		}
    	cin>>n;
    	while(n--){
    		cin>>x;
    		if(sqr((long long)sqrt(x))!=x) cout<<"NO"<<endl;
    		else if(composite[(int)sqrt(x)]) cout<<"NO"<<endl;
    		else cout<<"YES"<<endl;
    	}
    }
    

    【C. Shifts】

      http://www.codeforces.com/contest/230/problem/C

      做div1的时候这个题挂了,很囧……

      题目大意:给一个01矩阵,行可以转(密码锁那样),问最少转几次出现一列全是1.

      mov[i][j]表示使第i行第j列出现1的最少移动次数。循环的数组显然要拆分一下,然后正着倒着各一边dp,最后枚举列统计一下就ok了……

    #include <iostream>
    #include <cstring>
    using namespace std;
    template<class T>inline void gmin(T &a,T b){if(a>b)a=b;}
    
    char s[10010];
    int n,m,ans=2147483647,mov[110][10010],tmp;
    
    int main(){
    	cin>>n>>m;
    	for(int i=1;i<=n;i++)
    		for(int j=0;j<m;j++) mov[i][j]=1000000;
    	for(int i=1;i<=n;i++){
    		cin>>s;
    		for(int j=0;j<m;j++)
    			if(s[j]=='1') mov[i][j]=0;
    		for(int j=0;j<m<<1;j++)
    			gmin(mov[i][j%m],mov[i][(j-1+m)%m]+1);
    		for(int j=(m<<1)-1;j>=0;j--)
    			gmin(mov[i][j%m],mov[i][(j+1)%m]+1);
    	}
    	for(int j=0;j<m;j++){
    		tmp=0;
    		for(int i=1;i<=n;i++)
    			tmp+=mov[i][j];
    		gmin(ans,tmp);
    	}
    	cout<<(ans>=1000000?-1:ans)<<endl;
    }
    

    【D. Planets】

      http://www.codeforces.com/contest/230/problem/D

      题目大意:无向图从1走到n,某些特殊时间某些特殊点不能出发,问最短时间。

      大概算法就是最短路就行(比如SPFA),复杂度瓶颈在于如何知道某一点某一时刻能不能走,可以对于每个点建一个查找树,就过了。C++用map或者set都行。

    #include <iostream>
    #include <cstring>
    #include <queue>
    #include <map>
    #define mn 100010
    #define mm 200010
    using namespace std;
    
    map<int,bool> bst[mn];
    queue<int> q;
    int n,m,a,b,c,dist[mn];
    bool vis[mn];
    
    struct EDGE{
    	int pnt,dist;
    	EDGE *pre;
    	EDGE(){}
    	EDGE(int _pnt,int _dist,EDGE *_pre):pnt(_pnt),pre(_pre),dist(_dist){}
    }Edge[mm],*SP=Edge,*edge[mn];
    
    inline void addedge(int a,int b,int c){
    	edge[a]=new(++SP)EDGE(b,c,edge[a]);
    	edge[b]=new(++SP)EDGE(a,c,edge[b]);
    }
    
    int main(){
    	cin>>n>>m;
    	while(m--){
    		cin>>a>>b>>c;
    		addedge(a,b,c);
    	}
    	for(int i=1;i<=n;i++){
    		cin>>a;
    		while(a--){
    			cin>>b;
    			bst[i][b]=true;
    		}
    	}
    	memset(dist,0x7f,sizeof(dist));
    	dist[1]=0;
    	q.push(1);
    	while(!q.empty()){
    		int i=q.front();q.pop();
    		vis[i]=false;
    		int cur_time=dist[i];
    		while(bst[i][cur_time]) cur_time++;
    		for(EDGE *j=edge[i];j;j=j->pre)
    			if(j->dist+cur_time<dist[j->pnt]){
    				dist[j->pnt]=cur_time+j->dist;
    				if(!vis[j->pnt]){
    					vis[j->pnt]=true;
    					q.push(j->pnt);
    				}
    			}
    	}
    	cout<<(dist[n]==dist[0]?-1:dist[n])<<endl;
    }
    

    【E. Triangles】

      http://www.codeforces.com/contest/230/problem/E

      题目大意:一个完全图,拆成两部分,问这两部分一共有多少三角形。

      完全图中共有C(n,3)个三角形,对于某个点x,如果有deg[x]个点与x相连,那么剩下(n-x-1)个点就不与x相连了,于是就减少了deg[x]*(n-deg[x]-1)个包含x的三角形(乘法原理)。最后处理一下重复统计。

    #include <cstdio>
    int m,a,b,deg[1000010];
    long long n,tri;
    int main(){
    	scanf("%I64d%d",&n,&m);
    	while(m--){
    		scanf("%d%d",&a,&b);
    		deg[a]++,deg[b]++;
    	}
    	for(int i=1;i<=n;i++)
    		tri+=(long long)deg[i]*(n-deg[i]-1);
    	tri>>=1;
    	printf("%I64d\n",n*(n-1)*(n-2)/6-tri);
    }
    

      Div1努力搞中……

  • 相关阅读:
    vim讲解
    tar常用解包
    linux扩展权限
    为Virtualbox中的Solaris10安装VBoxAdditions
    Solaris10下Telnet、SSH、ftp使用root登录
    linux软链接和硬链接
    curl命令学习(转载的)
    linux磁盘分区fdisk命令详解
    在服务器上排除问题的头五分钟
    Java对文件压缩/加密/解密/解压缩的例子,DES/RSA
  • 原文地址:https://www.cnblogs.com/Delostik/p/2710655.html
Copyright © 2011-2022 走看看