计算机学院大学生程序设计竞赛(2015’11)

16 篇文章 0 订阅
15 篇文章 0 订阅

额,貌似都是暴力,除了油菜花那个用了数据结构。考验细心与编程能力。挺不错的 。

1001,搬砖
题意:给你一个数字,把数字分为2半,代价是分开后二者的差值。要求最后全部是1。
解法:用dfs(n):表示把n分为2半需要的代价。

//#define CF
#ifndef CF
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#include<set>
#include<vector>
#else
#include<bits/stdc++.h>
#endif // CF
using namespace std;
#define LL long long
#define pb push_back
#define X first
#define Y second
#define cl(a,b) memset(a,b,sizeof(a))
typedef pair<long long ,long long > P;
const int maxn=10000005;
const LL inf=1LL<<50;
const LL mod=1e9+7;
int dfs(int n){
    if(n==1)return 0;
    if(n==2)return 0;
    if(n&1)return dfs(n/2+1)+dfs(n/2)+1;
    else return dfs(n/2)+dfs(n/2);
}
int main() {
    int T;scanf("%d",&T);
    while(T--){
        int n;scanf("%d",&n);
        printf("%d\n",dfs(n));
    }
    return 0;
}

1002 投币洗衣机
题意:告诉衣服数量在[a,b)–>2,[b,c)–>3,[c,+oo)–>4.然后每天有衣服的数量,一旦衣服数量达到区间就计算。
解答:用一个计数器,累计衣服的数量

//#define CF
#ifndef CF
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#include<set>
#include<vector>
#else
#include<bits/stdc++.h>
#endif // CF
using namespace std;
#define LL long long
#define pb push_back
#define X first
#define Y second
#define cl(a,b) memset(a,b,sizeof(a))
typedef pair<long long ,long long > P;
const int maxn=10000005;
const LL inf=1LL<<50;
const LL mod=1e9+7;

int main() {
    int n,a,b,c;
    while(~scanf("%d%d%d%d",&n,&a,&b,&c)){
        int sum=0;
        int x_sum=0;
        for(int i=0;i<n;i++){
            int x;scanf("%d",&x);
            x_sum+=x;
            if(x_sum>=a&&x_sum<b){
                sum+=2;x_sum=0;
            }
            else if(x_sum>=b&&x_sum<c){
                sum+=3;x_sum=0;
            }
            else if(x_sum>=c){
                sum+=4;x_sum=0;
            }
        }
        printf("%d\n",sum);
    }
    return 0;
}

1003 玩骰子
题意:给你A,B二人的筛子,情况,按照题目要求的比较规则,如果A再扔一次筛子的获胜概率。
解法:实际上是掷某一个骰子后,某个筛子能带来的最大胜率。写一个判断函数,暴力枚举

//#define CF
#ifndef CF
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#include<set>
#include<vector>
#else
#include<bits/stdc++.h>
#endif // CF
using namespace std;
#define LL long long
#define pb push_back
#define X first
#define Y second
#define cl(a,b) memset(a,b,sizeof(a))
typedef pair<long long ,long long > P;
const int maxn=50505*2;
const LL inf=1LL<<50;
const LL mod=1e9+7;

bool isThree(int b[]){
    return b[0]==b[1]&&b[1]==b[2];
}
bool isTwo(int b[]){
    return b[0]==b[1]||b[1]==b[2];
}
int get_(int a[]){
    if(a[0]==a[1])return a[2];
    if(a[1]==a[2])return a[0];
}
int getdb(int a[]){
    if(a[0]==a[1])return a[0];
    if(a[1]==a[2])return a[1];
}

bool pan(int *a,int *b){
    if(isThree(a)){
        if(isThree(b)&&b[0]>=a[0])return 0;
        return 1;
    }
    else if(isTwo(a)){
        if(isThree(b))return 0;
        else if(isTwo(b)){
            if(getdb(a)>getdb(b))return 1;
            else if(getdb(a)==getdb(b)&&get_(a)>get_(b))return 1;
            else return 0;
        }
        else return 1;
    }
    else {
        if(isThree(b))return 0;
        else if(isTwo(b))return 0;
        else {
            for(int i=2;i>=0;i--){
                if(a[i]==b[i])continue;
                return a[i]>b[i];
            }
            return 0;
        }
    }
}
void Copy(int* a,int* b){
    for(int i=0;i<3;i++)a[i]=b[i];
}

int aa[3];
int a[3],b[3];
int main() {
    int T;scanf("%d",&T);
    while(T--){
        for(int i=0;i<3;i++){
            cin>>a[i];aa[i]=a[i];
        }
        sort(a,a+3);
        for(int i=0;i<3;i++){
            cin>>b[i];
        }
        sort(b,b+3);

        if(pan(a,b)){
            printf("1.000\n");continue;
        }

        double ans=0;
        for(int i=0;i<3;i++){
            double tmp=0;
            for(int j=1;j<=6;j++){
                Copy(a,aa);
                a[i]=j;
                sort(a,a+3);
                if(pan(a,b))tmp+=1.0/6.0;
            }
            ans=max(ans,tmp);
        }
        printf("%.3lf\n",ans);
    }
    return 0;
}

1004 质方数
题意:给你一个数,找到一个数是质数,且平方最接近给出的数n
解法:二分查找,先生成质方数的表,二分查找。

//#define CF
#ifndef CF
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#include<set>
#include<vector>
#else
#include<bits/stdc++.h>
#endif // CF
using namespace std;
#define LL long long
#define pb push_back
#define X first
#define Y second
#define cl(a,b) memset(a,b,sizeof(a))
typedef pair<long long ,long long > P;
const int maxn=10605;
const LL inf=1LL<<50;
const LL mod=1e9+7;
bool p[maxn];
LL st[maxn];
int init(){
    p[0]=p[1]=1;
    for(int i=2;i<maxn;i++)if(!p[i]){
        for(int j=i+i;j<maxn;j+=i){
            p[j]=1;
        }
    }
    int num=0;
    //for(int i=1;i<10;i++)if(!p[i])printf("%d\n",i);
    for(int i=1;i<maxn;i++)if(!p[i]){
        st[num++]=(LL)i*i;
    }
    return num;
}
int main() {
    int N=init();
    //for(int i=0;i<10;i++)printf("%lld\n",st[i]);
    int T;scanf("%d",&T);
    while(T--){
        LL n;scanf("%lld",&n);
        int x,y;
        x=lower_bound(st,st+N,n)-st;
        if(st[x]==n)printf("%lld\n",st[x]);
        else {
            int xx=x;
            if(xx>1)xx--;
            int yy=x;
            if(n-st[xx]<st[yy]-n){
                printf("%lld\n",st[xx]);
            }
            else {
                printf("%lld\n",st[yy]);
            }
        }
    }
    return 0;
}

1005 ACM组队安排
题意:给你一个数n,然后可以分为1-3,人组队。问分法,不能重复。
解法:递推,ans[n]:n个人的组合数,考虑第n个人,单独的话,那么其他的是ans[n-1],如果,在n-1人选择一个和n组合,那么有C(n-1,1)选法,那么还剩ans[n-2],就是C(n-1,1) * ans[n-2],若果选择2个组队,那么就是C(n-1,2),对应ans[n-3],总计C(n-1,2) * ans[n-3],所以总计:ans[n]=ans[n-1]+(n-1) * ans[n-2]+(n-1) * (n-2)/2 * ans[n-3]

//#define CF
#ifndef CF
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#include<set>
#include<vector>
#else
#include<bits/stdc++.h>
#endif // CF
using namespace std;
#define LL long long
#define pb push_back
#define X first
#define Y second
#define cl(a,b) memset(a,b,sizeof(a))
typedef pair<long long ,long long > P;
const int maxn=50505*2;
const LL inf=1LL<<50;
const LL mod=1e9+7;
LL ans[21];
void init(){
    ans[1]=1;ans[2]=2;ans[3]=5;
    for(int i=4;i<=20;i++){
        ans[i]=ans[i-1]+(i-1)*ans[i-2]+(i-1)*(i-2)/2*ans[i-3];
    }
}
int main() {
    int n;
    init();
    while(~scanf("%d",&n)&&n!=0) {
        printf("%lld\n",ans[n]);
    }
    return 0;
}

1006 逆袭指数
题意:找出一个数的最大连续因子积
解答:暴力,素数直接判断,其他的暴力计算

//#define CF
#ifndef CF
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#include<set>
#include<vector>
#else
#include<bits/stdc++.h>
#endif // CF
using namespace std;
#define LL long long
#define pb push_back
#define X first
#define Y second
#define cl(a,b) memset(a,b,sizeof(a))
typedef pair<long long ,long long > P;
const int maxn=5050;
const LL inf=1LL<<50;
const LL mod=1e9+7;

bool isp(LL n){
    if(n==1||n==0)return true;
    if(n==2)return false;
    for(int i=2;i*i<=n;i++)if(n%i==0)return false;
    return true;
}
LL f(int st,int len){
    LL fac=1;
    int i=0;while(i<len)fac*=st++,i++;
    return fac;
}
int main(){
    LL n;
    while(~scanf("%lld",&n)){

        if(isp(n)){
            printf("1\n%d\n",n);continue;
        }
        if(n==2){
            printf("1\n2\n");continue;
        }
        LL myst=0,len=0;
        for(int st=2;st*st<=n;st++){
            for(int j=1;;j++){
                LL num=f(st,j);
                if(num>n)break;
                if(n%num==0){
                    if(j>len){
                        len=j;
                        myst=st;
                    }
                }
            }
        }
        printf("%lld\n",len);
        for(int i=myst;i<myst+len;i++){
            if(i==myst)printf("%d",i);
            else printf("*%d",i);
        }
        puts("");
    }
    return 0;
}

1007 油菜花王国
题意:给你一个关系图,以及每个点的权重,如果权重时斐波那契数,那么贡献是1.
解答:并查集或者连通图。

//#define CF
#ifndef CF
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#include<set>
#include<vector>
#else
#include<bits/stdc++.h>
#endif // CF
using namespace std;
#define LL long long
#define pb push_back
#define X first
#define Y second
#define cl(a,b) memset(a,b,sizeof(a))
typedef pair<long long ,long long > P;
const int maxn=50505*2;
const LL inf=1LL<<50;
const LL mod=1e9+7;
LL a[maxn];

vector<int> G[maxn];

int dfn[maxn],low[maxn],s[maxn];
int belong[maxn];
bool ins[maxn];
int cnt,num,top;

int my[maxn];
void dfs(int u){
    dfn[u]=low[u]=++num;
    s[++top]=u;
    ins[u]=true;
    int N=G[u].size();
    for(int i=0;i<N;i++){
        int v=G[u][i];
        if(!dfn[v]){
            dfs(v);
            low[u]=min(low[u],low[v]);
        }
        else if(ins[v]&&dfn[v]<low[u]){
            low[u]=dfn[v];
        }
    }
    if(low[u]==dfn[u]){
        cnt++;
        int v;
        do{
            v=s[top--];
            ins[v]=false;
            belong[v]=cnt;
            my[cnt]++;
        }while(v!=u);
    }
}

void Tarjan(int n){
    cnt=num=top=0;
    cl(dfn,0);
    cl(ins,false);
    cl(my,0);
    cl(belong,0);
    for(int i=1;i<=n;i++)if(!dfn[i]){
        dfs(i);
    }
}
LL fib[maxn];
void init(){
    fib[1]=fib[2]=1;
    for(int i=3;i<47;i++){
        fib[i]=fib[i-1]+fib[i-2];
        //printf("%lld\n",fib[i]);
        if(fib[i]>1000000001LL)break;
    }

}
bool used[1005][1005];
int main() {
    int n,m;
    init();
    while(~scanf("%d%d",&n,&m)){
        for(int i=0;i<maxn;i++)G[i].clear();
        cl(used,false);
        for(int i=1;i<=n;i++){
            scanf("%lld",&a[i]);
        }
        for(int i=0;i<m;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            if(u==v)continue;
            if(used[u][v]||used[v][u])continue;
            used[u][v]=used[v][u]=true;
            G[u].pb(v);
            G[v].pb(u);
        }
        Tarjan(n);
        int mx=0,id=0;
        for(int i=1;i<=cnt;i++){
            if(mx<my[i]){
                mx=my[i];
                id=i;
            }
        }
        LL ans=0;
        for(int i=1;i<=n;i++){
            if(belong[i]==id){
                for(int j=1;j<47;j++){
                    if(fib[j]==a[i]){
                        //cout<<i<<endl;
                        ans+=1;break;
                    }
                }
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}

1008 游乐场
题意:去玩,有几个地方必须去,每个地方有花费,然后如果钱剩余的多,那么可以去玩别的 。想尽可能玩的多。
解法:先去掉必须去的,然后排序,贪心。

//#define CF
#ifndef CF
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#include<set>
#include<vector>
#else
#include<bits/stdc++.h>
#endif // CF
using namespace std;
#define LL long long
#define pb push_back
#define X first
#define Y second
#define cl(a,b) memset(a,b,sizeof(a))
typedef pair<long long ,long long > P;
const int maxn=10605;
const LL inf=1LL<<50;
const LL mod=1e9+7;

struct node{
    LL val;int id;
    bool operator<(const node& t) const {
        return val<t.val;
    }
}x[maxn];
bool vis[maxn];
int main() {

    int T;scanf("%d",&T);
    while(T--){
        int n,m;LL k;
        scanf("%d%d%lld",&n,&m,&k);
        for(int i=1;i<=n;i++){
            scanf("%lld",&x[i].val);
            x[i].id=i;
        }
        cl(vis,false);
        LL p_sum=0;
        for(int i=1;i<=m;i++){
            int p;
            scanf("%d",&p);
            p_sum+=x[p].val;
            vis[p]=true;
        }

        if(p_sum>k){
            printf("-1\n");continue;
        }
        k-=p_sum;
        sort(x+1,x+n+1);
        //for(int i=1;i<=n;i++)printf("%lld\n",x[i]);
        int ans=m;
        for(int i=1;i<=n;i++)if(!vis[x[i].id]){
            if(k>=x[i].val){
                ans++;
                k-=x[i].val;
            }
            else break;
        }
        printf("%d\n",ans);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值