2015年江西理工大学C语言程序设计竞赛(高级组)

A

解法:DP+二分

dp[i]=max(dp[i],dp[j]+p[i].v)(i>j)

dp[i]表示建立i点之后能够获得的最大值

int n,M;

struct node
{
    int l,v;
}p[1010];
int dp[1010];

bool cmp(node a,node b){
    return a.l < b.l;
}

bool judge_oo(){
    int Max = -1;
    for(int i = 1;i <= n;i++) Max = max(Max,p[i].v);
    if(Max >= M) return 1;
    return 0;
}

bool judge_no(){
    int sum = 0;
    for(int i = 1;i <= n;i++) sum += p[i].v;
    if(sum >= M) return 0;
    return 1;
}

bool judge_DP(int L){
    memset(dp,0,sizeof dp);
    for(int i = 1;i <= n;i++){
        for(int j = 0;j < i; j++){
            if(p[i].l - p[j].l >= L){
                dp[i] = max(dp[i],dp[j] + p[i].v);
            }
        }
    }
    int ML = 0;
    for(int i = 1;i <= n;i++) ML = max(ML,dp[i]);
    if(ML >= M) return 1;
    return 0;
}

int solve(int L,int R){
    while(L + 1 < R){
        int mid = (L + R)/2;
        if(judge_DP(mid)) L = mid;
        else R = mid;
    }
    return L;
}

int main(int argc, char *argv[])
{
    //freopen("data.in","r",stdin);
    //freopen("data.out","w",stdout);
    int T;
    cin >> T;
    while(T--){
        cin >> n >> M;
        for(int i = 1;i <= n;i ++)
            cin >> p[i].l >> p[i].v;
        if(judge_no()){
            puts("-1");
            continue;
        }
        if(judge_oo()){
            puts("oo");
            continue;
        }
        sort(p+1,p+n+1,cmp);
        p[0].l = -100000000 , p[0].v = 0;
        int L = 1 , R = p[n].l;
        cout << solve(L,R) << endl;
    }
    return 0;
}

B

解法:模拟。字符串模拟

#include<stdio.h>
//#include<bits/stdc++.h>
#include<string.h>
#include<iostream>
#include<math.h>
#include<sstream>
#include<set>
#include<queue>
#include<map>
#include<vector>
#include<algorithm>
#include<limits.h>
#define inf 0x3fffffff
#define INF 0x3f3f3f3f
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define ULL unsigned long long
using namespace std;
int i,j;
int n,m;
int num_1,num_2;
int t;
int sum,ans,flag;
string s_1,s_2,s_3;
string sss;
string ss[10000];
string c;
map<string,int>q1;
map<string,int>q2;
int main()
{
    cin>>t;
    while(t--)
    {
        cin>>n>>c;
        num_1=0;
        for(i=0; i<n; i++)
        {
            cin>>sss;
            ans=sss.find(".");
            s_1=sss.substr(0,ans);
            s_2=sss.substr(ans+1,sss.length());
            if(s_2==c)
            {
                int ans_2=sss.find("(");
                int ans_3=sss.find(")");
                if((ans_2!=-1&&ans_2<ans_3))
                {
                    //  num_1++;
                    ss[num_1++]=sss.substr(0,ans_2);
                    //  cout<<sss.substr(0,ans_2)<<endl;
                }
                else if(ans_2==-1||ans_3==-1)
                {
                    //  num_1++;
                    ss[num_1++]=sss.substr(0,ans);
                    //    cout<<sss.substr(0,ans)<<endl;
                }
            }
        }
        for(i=0; i<num_1; i++)
        {
            //      cout<<ss[i]<<"A"<<endl;
        }
        // cout<<num_1<<endl;
        for(i=0; i<num_1; i++)
        {
            q1[ss[i]]++;
        }
        for(i=0; i<num_1; i++)
        {
            if(q2[ss[i]]==0)
            {
                q2[ss[i]]=1;
                if(q1[ss[i]]==1)
                {
                    cout<<ss[i]<<"."<<c<<endl;
                }
                else
                {
                    cout<<ss[i]<<"."<<c<<" "<<q1[ss[i]]<<endl;
                }
            }
        }
        q1.clear();
        q2.clear();
    }
    return 0;
}

C

解法:树状数组寻找逆序对+预处理

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>


using namespace std;

const int M = 200010;

long long ans[M + 10];
int G[M + 10],c[M + 10];


int Lowbit(int x)
{
    return x & (-x);
}

void Insert(int x,int d)
{
    while(x<=M){
        c[x]+=d;
        x+=Lowbit(x);
    }
}

int Sum(int x)
{
    int sum=0;
    while(x>0){
        sum+=c[x];
        x-=Lowbit(x);
    }
    return sum;
}


void init()
{
    memset(G,-1,sizeof G);
    memset(ans,0,sizeof ans);
    memset(c,0,sizeof c);
    G[1] = 1;
    for(int i = 2; i <= 200100;i++){
        if(G[i] == -1){
            for(int j = i;j <= 200100;j += i){
                if(G[j] == -1){
                    G[j] = i;
                }
            }
        }
    }
    for(int i=1;i<=200005;i++)
    {
        Insert(G[i],1);
        ans[i] = ans[i-1] + (i-Sum(G[i]));
    }
}

int main()
{
    init();
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        cout<<ans[n]<<endl;
    }
    return 0;
}

D

解法:模版题,最小覆盖圆

#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
const double eps=1e-8;
struct Point{
    double x,y;
}p[505];
double dis(const Point &a,const Point &b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
Point circumcenter(const Point &a,const Point &b,const Point &c)
{ //返回三角形的外心
    Point ret;
    double a1=b.x-a.x,b1=b.y-a.y,c1=(a1*a1+b1*b1)/2;
    double a2=c.x-a.x,b2=c.y-a.y,c2=(a2*a2+b2*b2)/2;
    double d=a1*b2-a2*b1;
    ret.x=a.x+(c1*b2-c2*b1)/d;
    ret.y=a.y+(a1*c2-a2*c1)/d;
    return ret;
}
void min_cover_circle(Point *p,int n,Point &c,double &r){ //c为圆心,r为半径
    random_shuffle(p,p+n); //
    c=p[0]; r=0;
    for(int i=1;i<n;i++)
    {
        if(dis(p[i],c)>r+eps)  //第一个点
        {
            c=p[i]; r=0;
            for(int j=0;j<i;j++)
                if(dis(p[j],c)>r+eps) //第二个点
                {
                    c.x=(p[i].x+p[j].x)/2;
                    c.y=(p[i].y+p[j].y)/2;
                    r=dis(p[j],c);
                    for(int k=0;k<j;k++)
                        if(dis(p[k],c)>r+eps) //第三个点
                        {//求外接圆圆心,三点必不共线
                            c=circumcenter(p[i],p[j],p[k]);
                            r=dis(p[i],c);
                        }
                }
        }
    }
}
int main(){
    int n;
    Point c;
    double r;
    int t;
    cin>>t;
    while(t--)
    {
        cin>>n;
        for(int i=0; i<n; i++)
            scanf("%lf%lf",&p[i].x,&p[i].y);
        min_cover_circle(p,n,c,r);
        printf("%.1f %.1f
",c.x,c.y);
    }
 
    return 0;
}
原文地址:https://www.cnblogs.com/yinghualuowu/p/6115544.html