湘潭大学2017年下学期程序设计实践-模拟测试2 题解

来源:互联网 发布:网络卡牌类游戏 编辑:程序博客网 时间:2024/06/05 04:39

XTU 1298 Position

http://202.197.224.59/exam/index.php/problem/exam_read/id/1298/exam_id/229

思路:
1.数据很水,其实可以暴力过(当然,说的是优雅的暴力);
2.可以推数学公式;
3.计算前缀和然后二分查找。

根据n的数据范围可知,数组开到1e5足够了:
((1+1e5)*1e5/2) > 1e9

#include <bits/stdc++.h>using namespace std;#define ll long longll ans[100005];int main(){    for(int i=1;i<=1e5;i++)        ans[i]=ans[i-1]+i;    int n;    while(cin>>n)    {        int pos = lower_bound(ans,ans+100000,n)-ans;        cout<<pos<<" "<<n-ans[pos-1]<<endl;    }    return 0;}

XTU 1299 String

http://202.197.224.59/exam/index.php/problem/exam_read/id/1299/exam_id/229

思路:直接暴力模拟一下就好,送分题,注意每个样例之间要换行。

#include<bits/stdc++.h>using namespace std;int main(){    char s[101],t[101];    while(scanf("%s",s)!=EOF){        int ca=1;        while(scanf("%s",t)!=EOF){            if(t[0]=='E')            {                printf("\n");                break;            }            else if(t[0]=='S')            {                int a,b;                char c[2];                scanf("%d%d%s",&a,&b,c);                for(int i=a-1;i<b;++i)                s[i]=c[0];                printf("%d:%s\n",ca++,s);            }            else            {                char c[2],d[2];                scanf("%s%s",c,d);                for(int i=0;i<strlen(s);i++)                {                    if(s[i]==c[0])                    s[i]=d[0];                }                printf("%d:%s\n",ca++,s);            }        }    }    return 0;}

XTU 1300 Dice

http://202.197.224.59/exam/index.php/problem/exam_read/id/1300/exam_id/229

思路:
1.记录一下每种数值各出现多少次;(初始化为cnt[7]={0};)
2.对于每次询问,如果询问的点数是1,那么比较cnt[1]和n的值谁大;如果询问的点数不是1,那么比较cnt[1] + cnt[k] 和 n 的值谁大。

#include <bits/stdc++.h>using namespace std;int main(){    int t ;    cin>>t;    char s[10];    int m;    while(t--)    {        scanf("%s%d",s,&m);        int cnt[7]={0};        for(int i=0;i<6;i++)            cnt[s[i]-'0']++;        int ca=1;        while(m--)        {            int n,k;            int ok=0;            scanf("%d%d",&n,&k);            if(k==1)            {                if(n<=cnt[k])                    ok=1;            }            else            {                if(n<=cnt[k]+cnt[1])                    ok=1;            }            cout<<ca++<<((ok)?":true\n":":false\n");        }        cout<<endl;    }    return 0;}

XTU 1301 Zeroes

http://202.197.224.59/exam/index.php/problem/exam_read/id/1301/exam_id/229

思路:
暴力模拟一下过程便可。

#include <bits/stdc++.h>using namespace std;int main(){    int t;    cin>>t;    while(t--)    {        int n;cin>>n;        int a[20];        for(int i=1;i<=n;i++)            scanf("%d",a+i);        int ans=0;        while(ans<=1000)//最多循环1000次,复杂度O(1000*t*n)        {            int maxv=*max_element(a+1,a+1+n);            //取最大值若等于0,说明数组里面所有数字都是0            if(maxv==0)break;            ans++;            int fst=a[1];            for(int i=1;i<n;i++)                a[i]=abs(a[i]-a[i+1]);            a[n]=abs(a[n]-fst);        }        if(ans<=1000)        cout<<ans<<endl;        else cout<<"Impossible\n";    }    return 0;}

XTU 1302 Balance Tree

http://202.197.224.59/exam/index.php/problem/exam_read/id/1302/exam_id/229

思路:建树+判断便可。

#include <bits/stdc++.h>using namespace std;struct node{    int v;    node *l,*r;    node():l(NULL),r(NULL){};    node(int v):v(v),l(NULL),r(NULL){};};void build(node* u,int val){    if(val < u->v)    {        if(u->l!=NULL)            build(u->l,val);        else        {            u->l = new node(val);        }    }    else    {        if(u->r!=NULL)            build(u->r,val);        else        {            u->r = new node(val);        }    }}int getTreeDeep(node *root){if (root == NULL)return 0;int deepLeft = getTreeDeep(root->l);int deepRight = getTreeDeep(root->r);return deepLeft >= deepRight ? (deepLeft + 1) : (deepRight + 1);}bool isBalanceTree(node *root){if (root == NULL)return true;if (abs(getTreeDeep(root->l) - getTreeDeep(root->r)) > 1)return false;return isBalanceTree(root->l) && isBalanceTree(root->r);}int main(){    int t;cin>>t;    while(t--)    {        int n;        scanf("%d",&n);        n--;        int x;        scanf("%d",&x);        node* root = new node(x);        while(n--)        {            scanf("%d",&x);            build(root,x);        }        if(isBalanceTree(root))cout<<"Yes\n";        else cout<<"No\n";    }    return 0;}

XTU 1303 Sequence

http://202.197.224.59/exam/index.php/problem/exam_read/id/1303/exam_id/229

没做。

UPD:蜜汁爆ULL之后终于AC。。。

思路:

1.我们要得到区间[1,n]的最小代价,我们知道,区间[1,n]的最小代价只能由
区间[2,n]或者区间[1,n-1]得到

那么我们怎么知道区间[2,n]和区间[1,n-1]的最小代价呢?

我们分别需要知道区间[3,n] 区间[2,n-1] 区间[2,n-1] 区间[1,n-2]的最小代价……

如此下来,我们发现,再往下搜索答案的时候,会遇到区间[l,r]使得l>r,这种情况时,因为这种区间是不存在的,因此最小代价为0.

到这一步之后,我们回溯,就可以把上一步再上一步直到区间[1,n]的值全部求出来。

注意精度,一定要注意精度,一定要注意这个该死的精度

#include <bits/stdc++.h>using namespace std;#define ll unsigned long longint a[64];int t;int n;ll dp[64][64];ll base[64];ll dfs(int l,int r,int step){    if(l>r)return 0;    if(dp[l][r])return dp[l][r];    ll ret=min(dfs(l+1,r,step+1)+(ll)a[l]*base[step],               dfs(l,r-1,step+1)+(ll)a[r]*base[step]);    return dp[l][r]=ret;}int main(){    base[0]=1;    for(int i=1;i<61;i++)        base[i]=base[i-1]<<1;    cin>>t;    while(t--)    {        memset(dp,0,sizeof(dp));        scanf("%d",&n);        for(int i=1;i<=n;i++)        {            scanf("%d",a+i);        }        cout<<dfs(1,n,0)<<"\n";    }    return 0;}
阅读全文
0 0
原创粉丝点击