[Offer收割]编程练习赛1

来源:互联网 发布:免流源码 编辑:程序博客网 时间:2024/05/08 22:24

做了三题,题目都比较暴力。


A题

题目链接:A题


题意:给你一个三阶的幻方,三阶幻方指的是将1~9不重复的填入一个3*3的矩阵当中,使得每一行、每一列和每一条对角线的和都是相同的。现在准备将一个三阶幻方中的一些数组抹掉(0代替),交给你来进行还原,并且希望她能够判断出究竟是不是只有一组解。

如果只有一组解,输出该三阶幻方。如果多组解,输出“Too Many”。(题目保证有解)


题解:纯暴力,枚举被抹去位置的情况,并且判重加记录就可以做出来。时间复杂度O(9!)。


代码:

#include<cstdio>#include<cstring>#include<iostream>#include<sstream>#include<algorithm>#include<vector>#include<bitset>#include<set>#include<queue>#include<stack>#include<map>#include<cstdlib>#include<cmath>#define PI 2*asin(1.0)#define LL long long#define pb push_back#define pa pair<int,int>#define clr(a,b) memset(a,b,sizeof(a))#define lson lr<<1,l,mid#define rson lr<<1|1,mid+1,r#define bug(x) printf("%d++++++++++++++++++++%d\n",x,x)#define key_value ch[ch[root][1]][0]const int  MOD = 1000000007;const int N = 1e5+15;const int maxn = 450;const int letter = 130;const int INF = 15000000;const double pi=acos(-1.0);const double eps=1e-8;using namespace std;inline int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}int c[20],b[20],a[20],vis[20],dis[20],sum=0;bool solve(int x,int y,int z){    return b[x]+b[y]+b[z]==15;}void dfs(int x,int f){   b[x]=f;   vis[f]=1;   if(x==9){       if(solve(1,2,3)&&solve(4,5,6)&&solve(7,8,9)&&solve(1,4,7)&&solve(2,5,8)&&solve(3,6,9)&&solve(1,5,9)&&solve(3,5,7)) {           for(int i=1;i<=9;i++) c[i]=b[i];           sum++;       }       return;   }     if(a[x+1]) dfs(x+1,a[x+1]);     else for(int i=1;i<=9;i++){            if(!vis[i]&&!dis[i]) dfs(x+1,i),vis[i]=0;          }}int main(){    for(int i=1;i<=9;i++) scanf("%d",a+i),dis[a[i]]=1;    dfs(0,0);    if(sum==1) {        for(int i=1;i<=9;i++){            if(i%3==1) printf("%d",c[i]);            else printf(" %d",c[i]);            if(i%3==0) printf("\n");        }    }    else puts("Too Many");    return 0;}

B题:

题目链接:B题


题意:(中文题简单易懂)


题解:我们注意到随着缓存区K的增大,总延迟惩罚是在减少的,再看n的的大小只有100000,直接二分可做,并且可以利用优先队列维护最大值即可。

时间复杂度O(logn*logn)


代码:

#include<cstdio>#include<cstring>#include<iostream>#include<sstream>#include<algorithm>#include<vector>#include<bitset>#include<set>#include<queue>#include<stack>#include<map>#include<cstdlib>#include<cmath>#define PI 2*asin(1.0)#define LL long long#define pb push_back#define pa pair<int,int>#define clr(a,b) memset(a,b,sizeof(a))#define lson lr<<1,l,mid#define rson lr<<1|1,mid+1,r#define bug(x) printf("%d++++++++++++++++++++%d\n",x,x)#define key_value ch[ch[root][1]][0]const int  MOD = 1000000007;const int N = 1e5+15;const int maxn = 450;const int letter = 130;const int INF = 1e17;const double pi=acos(-1.0);const double eps=1e-8;using namespace std;inline int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}LL n,ps,a[N];bool solve(LL x){    LL sum=0,vv=1;    priority_queue<LL>q;    while(!q.empty()) q.pop();    for(LL i=1;i<=n;i++){        if(q.size()<x) {            q.push(a[i]);        }        else {            sum+=vv*q.top();            q.pop();            vv++;            q.push(a[i]);        }        if(sum>ps) return 0;    }    while(!q.empty()){        sum+=vv*q.top();        q.pop();        vv++;        if(sum>ps) return 0;    }  ///  printf("%lld %lld\n",x,sum);    return 1;}int main(){    scanf("%lld%lld",&n,&ps);    for(int i=1;i<=n;i++) scanf("%lld",a+i);    LL l=1,r=n;    LL ans=INF;    while(l<=r){        LL mid=(l+r)/2;        if(solve(mid)){            ans=min(ans,mid);            r=mid-1;        }        else {            l=mid+1;        }    }    if(ans!=INF)printf("%lld\n",ans);    else puts("-1");    return 0;}


C题

题目链接:C题


题意:(中文题简单易懂)


题解:仔细分析下可以看出是完全背包,但是有一些要注意的。背包的容量应该为2*k,因为建筑值肯定要超过k的。而且注意特判下,当建筑值大于等于k的时候单独拿出来计算,因为假如我的建筑值为3k 4k的时候肯定是背包更新不到的,所以特判下。时间复杂度:O(q*n*k*m)。


代码:

#pragma comment(linker, "/STACK:102400000,102400000")#include<cstdio>#include<cstring>#include<iostream>#include<sstream>#include<algorithm>#include<vector>#include<bitset>#include<set>#include<queue>#include<stack>#include<map>#include<cstdlib>#include<cmath>#define PI 2*asin(1.0)#define LL long long#define pa pair<int,int>#define pb push_back#define clr(a,b) memset(a,b,sizeof(a))#define lson lr<<1,l,mid#define rson lr<<1|1,mid+1,r#define bug(x) printf("%d++++++++++++++++++++%d\n",x,x)const int  MOD = 1000000007;const int N = 100+15;const int maxn = 2e4 + 14;const int INF = 1e17;const int letter = 130;const double pi=acos(-1.0);const double eps=1e-10;using namespace std;inline int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}int tc;int n,m,k;LL a[N],b[N],dp[maxn],t;int main(){    scanf("%d",&tc);    while(tc--){        LL sum=0;        int flag=0;        scanf("%d%d%d%lld",&n,&m,&k,&t);        for(int i=1;i<=m;i++) scanf("%lld",&a[i]);        for(int i=1;i<=m;i++) scanf("%lld",&b[i]);        for(int i=1;i<=n;i++){                LL ans=INF;                for(int j=1;j<=2*k;j++) dp[j]=INF;                for(int j=1;j<=m;j++){                    if(b[j]==0) continue;                    if(b[j]>=k) {                        ans=min(ans,a[j]);                        continue;                    }                    for(int x=b[j];x<=2*k;x++) dp[x]=min(dp[x-b[j]]+a[j],dp[x]);                }                for(int j=k;j<=2*k;j++) ans=min(ans,dp[j]);                for(int j=1;j<=m;j++) b[j]/=t;                if(ans==INF) {                    flag=1;                    break;                }                sum+=ans;        }        if(flag) puts("No Answer");        else printf("%lld\n",sum);    }    return 0;}


0 0
原创粉丝点击