• Codeforces 2


    A. Winner

            题目地址:http://codeforces.com/contest/2/problem/A

            题目大意:给出每一次比赛的得分情况,问最后得分最高的人。若最后分数同样,则输出分数同样的人中第一个分数不小于最后最高分数的人。

            算法讨论:用STL中的map和set维护就可以。

            Code:

    #include <iostream>
    #include <map>
    #include <set>
    #include <string>
    
    #define N 1000
    
    using namespace std;
    
    int n,Max,score[N+10];
    string name[N+10];
    set<string> Set;
    map<string,int> sum;
    
    int main(){
    	cin>>n;
    	for (int i=1;i<=n;++i){
    		cin>>name[i]>>score[i];
    		sum[name[i]]+=score[i];
    	}
    	for (map<string,int>::iterator i=sum.begin();i!=sum.end();++i)
    		if (i->second>Max) Max=i->second;
    	for (map<string,int>::iterator i=sum.begin();i!=sum.end();++i)
    		if (i->second==Max) Set.insert(i->first);
    	sum.clear();
    	for (int i=1;i<=n;++i)
    		if (Set.count(name[i])){
    			sum[name[i]]+=score[i];
    			if (sum[name[i]]>=Max){
    				cout<<name[i]<<endl;
    				return 0;
    			}
    		}
    }


    B. The least round way

            题目地址:http://codeforces.com/contest/2/problem/B

            题目大意:给出一个矩阵,求从左上角到右下角的一条路径,使得路径上的数的乘积后的0最少。

            算法讨论:

                    DP之。

                    分别求解从左上角到某一点的乘积中2的个数和5的个数,则0的个数为2的个数和5的个数中的较小值。

                    须要注意的是含0的情况。方法是读入的时候把0变成10,DP之,若答案大于1则使路径经过0就可以。

            Code:

    #include <cstdio>
    #include <algorithm>
    #include <stack>
    
    #define N 1000
    #define oo 0x7f7f7f7f
    
    using namespace std;
    
    int n,x,y,a[N+10][N+10],cnt[N+10][N+10][2],dp[N+10][N+10][2];
    bool f;
    stack<char> S;
    
    int main(){
    	scanf("%d",&n);
    	for (int i=0;i<=n;++i)
    		for (int j=0;j<=n;++j) dp[i][j][0]=dp[i][j][1]=oo;
    	for (int i=1;i<=n;++i)
    		for (int j=1;j<=n;++j){
    			scanf("%d",&a[i][j]);
    			if (!a[i][j]) f=1,x=i,y=j,a[i][j]=10;
    			for (int t=a[i][j];t%2==0;t/=2,cnt[i][j][0]++);
    			for (int t=a[i][j];t%5==0;t/=5,cnt[i][j][1]++);
    		}
    	dp[1][1][0]=cnt[1][1][0];
    	dp[1][1][1]=cnt[1][1][1];
    	for (int i=1;i<=n;++i)
    		for (int j=1;j<=n;++j){
    			if (i==1 && j==1) continue;
    			dp[i][j][0]=min(dp[i-1][j][0],dp[i][j-1][0])+cnt[i][j][0];
    			dp[i][j][1]=min(dp[i-1][j][1],dp[i][j-1][1])+cnt[i][j][1];
    		}
    	if (f && min(dp[n][n][0],dp[n][n][1])>1){
    		printf("1
    ");
    		for (int i=1;i<x;++i) printf("D");
    		for (int i=1;i<y;++i) printf("R");
    		for (int i=x;i<n;++i) printf("D");
    		for (int i=y;i<n;++i) printf("R");
    		return 0;
    	}
    	printf("%d
    ",min(dp[n][n][0],dp[n][n][1]));
    	if (dp[n][n][0]<dp[n][n][1]){
    		int i=n,j=n;
    		do{
    			if (i>1 && dp[i][j][0]==dp[i-1][j][0]+cnt[i][j][0]) i--,S.push('D');
    			else if (j>1) j--,S.push('R');
    		}while (i!=1 || j!=1);
    	}
    	else{
    		int i=n,j=n;
    		do{
    			if (i>1 && dp[i][j][1]==dp[i-1][j][1]+cnt[i][j][1]) i--,S.push('D');
    			else if (j>1) j--,S.push('R');
    		}while (i!=1 || j!=1);
    	}
    	while (!S.empty()) printf("%c",S.top()),S.pop();
    	puts("");
    	return 0;
    }


    C. Commentator problem

            题目地址:http://codeforces.com/contest/2/problem/C

            题目大意:给三个圆(互不包括),求一个点,使得这个点看三个圆的视角同样。

            算法讨论:模拟退火。

    初始状态为三个圆心的中心,估价函数为三个视角的一半的正弦值的平方和。

            Code:

    #include <cstdio>
    #include <cmath>
    
    #define N 300000
    #define eps 1e-20
    
    using namespace std;
    
    int xa,ya,ra,xb,yb,rb,xc,yc,rc;
    double x,y,v,delta;
    
    const int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
    
    inline double sqr(double x){
    	return x*x;
    }
    
    inline double dist(double x1,double y1,double x2,double y2){
    	return sqrt(sqr(x1-x2)+sqr(y1-y2));
    }
    
    inline double value(double x,double y){
    	double a1=ra/dist(x,y,xa,ya),a2=rb/dist(x,y,xb,yb),a3=rc/dist(x,y,xc,yc);
    	return sqr(a1-a2)+sqr(a2-a3)+sqr(a1-a3);
    }
    
    int main(){
    	scanf("%d%d%d",&xa,&ya,&ra);
    	scanf("%d%d%d",&xb,&yb,&rb);
    	scanf("%d%d%d",&xc,&yc,&rc);
    	x=(double)(xa+xb+xc)/3;
    	y=(double)(ya+yb+yc)/3;
    	v=value(x,y);
    	delta=1;
    	for (int i=0;i<N && v>eps;++i){
    		bool f=0;
    		for (int j=0;j<4;++j){
    			double xx=x+delta*dx[j],yy=y+delta*dy[j],vv;
    			if ((vv=value(xx,yy))<v) v=vv,x=xx,y=yy,f=1;
    		}
    		if (!f) delta*=.5;
    	}
    	if (value(x,y)<=eps) printf("%0.5lf %0.5lf
    ",x,y);
    	return 0;
    }


    By Charlie Pan

    Mar 4,2014

  • 相关阅读:
    NOIP2016 蚯蚓 题解
    BZOJ 1294 围豆豆 题解
    POJ1852 Ants 题解
    BZOJ 1131 [POI2008] STA-Station 题解
    HDU 5963 朋友 题解
    Codeforces 1292C Xenon's Attack on the Gangs 题解
    Emergency Evacuation 题解
    P4408 逃学的小孩 题解
    UVA11300 Spreading the Wealth 题解
    P2882 Face The Right Way G 题解
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/6971107.html
Copyright © 2020-2023  润新知