• AtCoder Beginner Contest 151 题解


    竟然顺利地AK了,爽到(
    传送门:https://atcoder.jp/contests/abc151

    A

    语法题

    #include<bits/stdc++.h>
    using namespace std;
    
    int main(){
    	char ch; cin>>ch;
    	cout<<(char)(ch+1);
    	return 0;
    }
    

    B

    简单的判断

    #pragma GCC optimize("O3")
    #include<bits/stdc++.h>
    using namespace std;
    #define endl '
    '
    #define debug(x) cerr << #x << ": " << x << endl
    #define pb(a) push_back(a)
    #define set0(a) memset(a,0,sizeof(a))
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define dwn(i,a,b) for(int i=(a);i>=(b);i--)
    #define ceil(a,b) (a+(b-1))/b
    #define INF 0x3f3f3f3f
    #define ll_INF 0x7f7f7f7f7f7f7f7f
    typedef long long ll;
    typedef pair<int,int> PII;
    typedef pair<double,double> PDD;
    
    inline void read(int &x) {
        int s=0;x=1;
        char ch=getchar();
        while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
        x*=s;
    }
    
    int main(){
    	int n, k, m; cin>>n>>k>>m;
    	
    	int sum=0;
    	rep(i,1,n-1){
    		int t; cin>>t;
    		sum+=t;
    	}
    	
    	if(sum+k<n*m) puts("-1");
    	else{
    		cout<<(n*m-sum>0? n*m-sum: 0)<<endl;
    	}
        return 0;
    }
    

    C

    简单的模拟

    #pragma GCC optimize("O3")
    #include<bits/stdc++.h>
    using namespace std;
    #define endl '
    '
    #define debug(x) cerr << #x << ": " << x << endl
    #define pb(a) push_back(a)
    #define set0(a) memset(a,0,sizeof(a))
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define dwn(i,a,b) for(int i=(a);i>=(b);i--)
    #define ceil(a,b) (a+(b-1))/b
    #define INF 0x3f3f3f3f
    #define ll_INF 0x7f7f7f7f7f7f7f7f
    typedef long long ll;
    typedef pair<int,int> PII;
    typedef pair<double,double> PDD;
    
    inline void read(int &x) {
        int s=0;x=1;
        char ch=getchar();
        while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
        x*=s;
    }
    
    const int N=1e5+5;
    bool ok[N];
    
    int main(){
    	int n, m; cin>>n>>m;
    	
    	int ac=0, pe[n+1]={0};
    	rep(i,1,m){
    		int id; string op; cin>>id>>op;
    		if(op=="AC" && !ok[id]){
    			ok[id]=true;
    			ac++;
    		}
    		else if(op=="WA" && !ok[id]) pe[id]++;
    	}
    	
    	int pen=0;
    	rep(i,1,n) if(ok[i]) pen+=pe[i];
    	cout<<ac<<' '<<pen<<endl;
    	
        return 0;
    }
    

    D

    看到范围,直接上bfs即可

    #pragma GCC optimize("O3")
    #include<bits/stdc++.h>
    using namespace std;
    #define endl '
    '
    #define debug(x) cerr << #x << ": " << x << endl
    #define pb(a) push_back(a)
    #define set0(a) memset(a,0,sizeof(a))
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define dwn(i,a,b) for(int i=(a);i>=(b);i--)
    #define ceil(a,b) (a+(b-1))/b
    #define INF 0x3f3f3f3f
    #define ll_INF 0x7f7f7f7f7f7f7f7f
    typedef long long ll;
    typedef pair<int,int> PII;
    typedef pair<double,double> PDD;
    
    inline void read(int &x) {
        int s=0;x=1;
        char ch=getchar();
        while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
        x*=s;
    }
    
    #define x first
    #define y second
    
    const int N=25;
    
    int n, m; 
    char g[N][N];
    
    PII q[N*N];
    bool vis[N][N];
    int d[N][N];
    
    int bfs(int sx, int sy, int tx, int ty){
    	if(sx==tx && sy==ty) return 0;
    	memset(vis, false, sizeof vis);
    	memset(d, 0x3f, sizeof d);
    	int hh=0, tt=-1;
    	q[++tt]={sx, sy}, d[sx][sy]=0;
    	
    	int dx[]={1, 0, -1, 0}, dy[]={0, 1, 0, -1};
    	
    	while(tt>=hh){
    		auto hd=q[hh++];
    		int x=hd.x, y=hd.y;
    		rep(i,0,3){
    			int kx=x+dx[i], ky=y+dy[i];
    			if(g[kx][ky]=='#' || vis[kx][ky]) continue;
    			if(kx<1 || kx>n || ky<1 || ky>m) continue;
    			
    			vis[kx][ky]=true;
    			d[kx][ky]=d[x][y]+1;
    			if(kx==tx && ky==ty) return d[kx][ky];
    			q[++tt]={kx, ky};
    		}
    	}
    	return -1;
    }
    
    int main(){
    	cin>>n>>m;
    	rep(i,1,n) rep(j,1,m) cin>>g[i][j];
    	
    	int res=-1;
    	rep(i,1,n) rep(j,1,m) rep(r,1,n) rep(c,1,m){
    		if(g[i][j]=='#' || g[r][c]=='#') continue;
    		res=max(res, bfs(i, j, r, c));
    	}
    	cout<<res<<endl;
    	
        return 0;
    }
    

    E

    考虑每个数可以造成的贡献,我们考察第 (i) 个数(这个数本身自然是被选取了),有三种情况:

    • 如果这个数的左右的数都有选取,那么贡献为 (0)
    • 如果选取的数在该数左边,那么贡献为 (C_{i-1}^{k-1}w_i)
    • 如果选取的数在该数右边,那么贡献为 (-C_{n-i}^{k-1}w_i)

    直接统计就行了:

    #pragma GCC optimize("O3")
    #include<bits/stdc++.h>
    using namespace std;
    #define endl '
    '
    #define debug(x) cerr << #x << ": " << x << endl
    #define pb(a) push_back(a)
    #define set0(a) memset(a,0,sizeof(a))
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define dwn(i,a,b) for(int i=(a);i>=(b);i--)
    #define ceil(a,b) (a+(b-1))/b
    #define INF 0x3f3f3f3f
    #define ll_INF 0x7f7f7f7f7f7f7f7f
    typedef long long ll;
    typedef pair<int,int> PII;
    typedef pair<double,double> PDD;
    
    inline void read(int &x) {
        int s=0;x=1;
        char ch=getchar();
        while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
        x*=s;
    }
    
    const int N=1e5+5, mod=1e9+7;
    
    ll fpow(ll x,ll p)
    {
        ll res=1;
        for(;p;p>>=1,x=x*x%mod)
            if(p&1)res=res*x%mod;
        return res%mod;
    }
    
    ll inv(ll x){
    	return fpow(x,mod-2)%mod;
    }
    
    ll fac[N];
    
    void init(){
    	fac[0]=1;
    	for(int i=1; i<N; i++) fac[i]=fac[i-1]*i%mod;
    }
    
    ll C(ll a, ll b){
    	return fac[a]*inv(fac[b])%mod*inv(fac[a-b])%mod;
    }
    
    int w[N];
    
    int main(){
    	init();
    	int n, k; cin>>n>>k;
    	rep(i,1,n) cin>>w[i];
    	
    	sort(w+1, w+1+n);
    	
    	ll res=0;
    	rep(i,1,n){
    		ll a=0, b=0;
    		if(k-1<=i-1) a=C(i-1, k-1);
    		if(n-i>=k-1) b=C(n-i, k-1);
    		res=(1LL*(a-b)*w[i]+res)%mod;
    	}
    	cout<<res<<endl;
    	
        return 0;
    }
    

    F

    似乎是最小圆覆盖的板子题,但我直接用模拟退火搞了hh

    #pragma GCC optimize("O3")
    #include<bits/stdc++.h>
    using namespace std;
    #define endl '
    '
    #define debug(x) cerr << #x << ": " << x << endl
    #define pb(a) push_back(a)
    #define set0(a) memset(a,0,sizeof(a))
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define dwn(i,a,b) for(int i=(a);i>=(b);i--)
    #define ceil(a,b) (a+(b-1))/b
    #define INF 0x3f3f3f3f
    #define ll_INF 0x7f7f7f7f7f7f7f7f
    typedef long long ll;
    typedef pair<int,int> PII;
    typedef pair<double,double> PDD;
    
    inline void read(int &x) {
        int s=0;x=1;
        char ch=getchar();
        while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
        x*=s;
    }
    
    #define x first
    #define y second
    
    const double eps=1e-12;
    
    const int N=55;
    int n;
    PDD q[N];
    
    double ans=1e5;
    
    double rand(double l, double r){
        return (double)rand()/RAND_MAX*(r-l)+l;
    }
    
    double get_dist(PDD u, PDD v){
    	return sqrt((u.x-v.x)*(u.x-v.x)+(u.y-v.y)*(u.y-v.y));
    }
    
    double calc(PDD p){
    	double res=0;
    	rep(i,1,n) res=max(res, get_dist(p, q[i]));
    	ans=min(ans, res);
    	return res;
    }
    
    void anneal(){
    	double ax=0, ay=0;
    	rep(i,1,n) ax+=q[i].x, ay+=q[i].y;
    	ax/=n, ay/=n;
    	
    	PDD cur(ax, ay);
    	for(double t=500; t>1e-4; t*=0.992){
    		PDD np(rand(cur.x-t, cur.x+t), rand(cur.y-t, cur.y+t));
    		double dt=calc(np)-calc(cur);
    		if(exp(-dt/t)>rand(0, 1)) cur=np;
    	}
    }
    
    int main(){
    	cin>>n;
    	rep(i,1,n){
    		double x, y; cin>>x>>y;
    		x-=500, y-=500;
    		q[i]={x, y};
    	}
    	random_shuffle(q+1, q+1+n);
    	
    	rep(i,1,100) anneal();
    	printf("%.10lf", ans);
    	
        return 0;
    }
    

    当然,因为就是一个最裸的最小圆覆盖问题,直接用最小圆覆盖板子就能过了:

    #include<bits/stdc++.h>
    using namespace std;
    
    const double eps=1e-12, pi=acos(-1);
    
    /*start-----------------------------------------------------------------*/
    
    #define x first
    #define y second
    
    struct Point{
    	double x, y;
    	Point(double x=0, double y=0): x(x), y(y){}
    	
    	Point operator + (const Point &p)const {return Point(x+p.x, y+p.y);}
    	Point operator - (const Point &p)const {return Point(x-p.x, y-p.y);}
    	Point operator * (const Point &p)const {return Point(x*p.x, y*p.y);}
    	Point operator / (const Point &p)const {return Point(x/p.x, y/p.y);}
    	
    	Point operator * (const double &k){return Point(x*k, y*k);}
    	Point operator / (const double &k){return Point(x/k, y/k);}	
    };
    
    struct Circle{
    	Point p;
    	double r;
    	Circle(Point p={0, 0}, double r=0): p(p), r(r){}
    };
    
    typedef Point Vector;
    
    int sign(double x){
    	if(fabs(x)<eps) return 0;
    	return x<0? -1: 1;
    }
    
    int cmp(double x, double y){
    	return sign(x-y);
    }
    
    bool operator < (const Point &a, const Point &b) {
    	return sign(a.x-b.x)<0 || sign(sign(a.x-b.x)==0 && sign(a.y-b.y)<0);
    }
    
    double dot(Vector A, Vector B){
    	return A.x*B.x+A.y*B.y;
    }
    
    double cross(Vector A, Vector B){
    	return A.x*B.y-A.y*B.x;
    }
    
    double get_length(Vector A){
    	return sqrt(dot(A, A));
    }
    
    double get_dist(Point a, Point b){
    	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    
    double get_angle(Vector A, Vector B){
    	return acos(dot(A, B)/get_length(A)/get_length(B));
    }
    
    double area(Point a, Point b, Point c){
    	return cross(b-a, c-a);
    }
    
    // 向量 A 顺时针旋转 angle 度
    Vector rotate(Vector A, double angle){
    	return Vector(A.x*cos(angle)+A.y*sin(angle), -A.x*sin(angle)+A.y*cos(angle));
    }
    
    Point get_line_intersection(Point p, Vector v, Point q, Vector w){
    	Vector u=p-q;
    	double t=cross(w, u)/cross(v, w);
    	return p+v*t;
    }
    
    // get perpendicular bisector 得到中垂线
    pair<Point, Vector> get_pbline(Point a, Point b){
    	return {(a+b)/2, rotate(b-a, pi/2)};
    }
    
    // 以两点为对径点作圆
    Circle get_circle(Point a, Point b){
    	return {(a+b)/2, get_dist(a, b)/2};
    }
    
    // 过三点作圆
    Circle get_circle(Point a, Point b, Point c){
    	auto u=get_pbline(a, b), v=get_pbline(a, c);
    	Point p=get_line_intersection(u.x, u.y, v.x, v.y);
    	return {p, get_dist(p, a)};
    }
    
    /*end--------------------------------------------*/
    
    const int N=55;
    
    Point q[N];
    int n;
    
    int main(){
    	cin>>n;
    	for(int i=1; i<=n; i++){
    		double x, y; cin>>x>>y;
    		q[i]={x, y};
    	}
    	
    	random_shuffle(q+1, q+1+n);
    	
    	Circle C={q[1], 0};
    	for(int i=2; i<=n; i++) if(cmp(C.r, get_dist(C.p, q[i]))==-1){
    		C={q[i], 0};
    		for(int j=1; j<i; j++) if(cmp(C.r, get_dist(C.p, q[j]))==-1){
    			C=get_circle(q[i], q[j]);
    			for(int k=1; k<j; k++) if(cmp(C.r, get_dist(C.p, q[k]))==-1){
    				C=get_circle(q[i], q[j], q[k]);
    			}
    		}
    	}
    	
    	printf("%.10lf
    ", C.r);
    	return 0;
    }
    
  • 相关阅读:
    【禅道】禅道安装步骤
    软件测试学习路线
    【mysql】mysql数据库安装
    【用例】测试用例阶段总结
    【坑】自动化测试之Excel表格
    开始.....
    网络攻防
    PAT/查找元素习题集
    PAT/简单模拟习题集(二)
    PAT/简单模拟习题集(一)
  • 原文地址:https://www.cnblogs.com/Tenshi/p/14886446.html
Copyright © 2020-2023  润新知