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

来源:互联网 发布:淘宝店铺装修图片链接 编辑:程序博客网 时间:2024/06/05 01:53

XTU 1304 ZUMA!

http://202.197.224.59/exam/index.php/problem/exam_read/id/1304/exam_id/230

思路:暴力乱搞即可。
1.找到2个相邻并且颜色与给你的小球相同的位置,然后我们假设把这个小球放在这里。
2.那么一开始,我们就消掉了2个球。
3.然后我们更新序列,删掉那两个球。判断序列中是否存在3个或以上的球连在一起。
4.若存在,继续删,并且记录下删了多少球。
5.不存在就退出,更新答案。

#include <bits/stdc++.h>using namespace std;int ans;string s;void doit(int id,char c){    string ss = s;    int cnt=2;    string now;    now = ss.substr(0,id-1);    now += ss.substr(id+1);    int flag=1;    while(flag)    {        flag=0;        for(int i=2;i<now.length();i++)        {            if(now[i-2]==now[i]&&now[i-1]==now[i])            {                int j=i;                while(now[j]==now[i]&&j<now.length())                {                    j++;                }                flag=1;                cnt+=(j-i+2);                ss = now.substr(0,i-2);                ss += now.substr(j);                break;            }        }        now=ss;    }    ans = max(ans,cnt);}int main(){    int t;    cin>>t;    int a[1010];    while(t--)    {        ans=0;        s.clear();        int n,c;        cin>>n>>c;        for(int i=1;i<=n;i++)        {            scanf("%d",a+i);            s+=(char)(a[i]+47);        }        char cc = (char)(c+47);        for(int i=1;i<s.length();i++)        {            if(s[i-1]==s[i]&&s[i]==cc)            doit(i,cc);        }        cout<<ans<<"\n";    }    return 0;}

XTU 1305 斐波那契区间

http://202.197.224.59/exam/index.php/problem/exam_read/id/1305/exam_id/230

思路:暴力枚举。
1.从序列的第三个开始枚举,如果当前值 == 前两个值之和,计数器+1
否则计数器置零。
2.每次都要更新答案。

#include <bits/stdc++.h>using namespace std;int main(){    int t;    cin>>t;    int a[10005];    int n;    while(t--)    {        cin>>n;        for(int i=1;i<=n;i++)            scanf("%d",a+i);        int ans=0;        int cnt=0;        for(int i=3;i<=n;i++)        {            if(a[i]==a[i-1]+a[i-2])            {                cnt++;                ans=max(ans,cnt);            }            else            {                ans=max(ans,cnt);                cnt=0;            }        }        cout<<ans+2<<endl;    }    return 0;}

XTU 1306 Love Number

http://202.197.224.59/exam/index.php/problem/exam_read/id/1306/exam_id/230

思路:签到题,只需判断(a-x)%d==0即可。

#include <bits/stdc++.h>using namespace std;int main(){    int t;    cin>>t;    while(t--)    {        int a,d,x;        scanf("%d%d%d",&a,&d,&x);        if((a-x)%d==0)            cout<<"Yes\n";        else cout<<"No\n";    }    return 0;}

XTU 1307 Beautiful Number

http://202.197.224.59/exam/index.php/problem/exam_read/id/1307/exam_id/230

思路:看起来很难,其实样例已经告诉我们1e18的范围内只有1700多个这样的数字,那么最佳做法就是离线打表啦。
(打表很粗暴,而且离线很麻烦,就不如暴搜,当然推公式也行,前提是会推)
其实我们也可以用暴搜来做,每次搜索到一个符合要求的答案就计数器+1,当然,暴搜不经过剪枝,最坏情况可达到2的63次方,因此我们对每次搜索加入一个“已访问过0”的标志
对于一个已访问过0的数字num,我们只需要搜num<<1|1;
而对于一个没访问过0的数字num,我们需要搜索num<<1和num<<1|1;
并且,在访问num<<1时,它的结尾一定是个0,所以我们需要把访问0标志带上。

下面的代码不是很精简

#include <bits/stdc++.h>using namespace std;#define ll long longint cnta,cntb;ll a,b;void dfsa(ll now,int cnt){    if(cnt>1)        return;    if(now>=a)        return;    if(cnt==1)        cnta++;    if(cnt==1)    {        dfsa(now<<1|1,cnt);    }    else    {        dfsa(now<<1,cnt+1);        dfsa(now<<1|1,cnt);    }}void dfsb(ll now,int cnt){    if(cnt>1)        return;    if(now>b)        return;    if(cnt==1)        cntb++;    if(cnt==1)    {        dfsb(now<<1|1,cnt);    }    else    {        dfsb(now<<1,cnt+1);        dfsb(now<<1|1,cnt);    }}int main(){    int t;    cin>>t;    while(t--)    {        cnta=cntb=0;        cin>>a>>b;        dfsa(1,0);        dfsb(1,0);        cout<<cntb-cnta<<"\n";    }    return 0;}

XTU 1308 比赛

http://202.197.224.59/exam/index.php/problem/exam_read/id/1308/exam_id/230

思路:
1.我们需要知道对于当前剩余的人数n,要拿出多少人去打比赛,那么暴力算一下就可以了,假设这个人数是base;
2.那么需要增加 base/2 场比赛(两两进行),并且新一轮剩下的人数是:

(n - base) + base/2 = n - base/2

就是:没去比赛的 + 参加比赛并且获胜的 = 目前剩余的

那么每次都这样搞一搞就好了

#include <bits/stdc++.h>using namespace std;#define ll long longint main(){    int t;    cin>>t;    while(t--)    {        ll n;cin>>n;        ll ans=0;        ll cnt=0;        while(n>1)        {            ll base=2;            while(base<=n)            {                base<<=1;            }            base>>=1;            cnt++;            ans+=base/2;            n -= base/2;        }        cout<<cnt<<" "<<ans<<endl;    }    return 0;}

XTU 1309 唯一的子串

http://202.197.224.59/exam/index.php/exam/problems/exam_id/230

思路:这题就STL乱搞,由于字符串长度较小,是很难超时的。

#include <bits/stdc++.h>using namespace std;set<string> st;int main(){    int t;    cin>>t;    while(t--)    {        st.clear();        int m;scanf("%d",&m);        string s;        cin>>s;        for(int i=0;i<s.length()-m+1;i++)        {            st.insert(s.substr(i,m));        }        for(set<string>::iterator it = st.begin();it!=st.end();it++)        {            cout<<*it<<"\n";        }        printf("\n");    }    return 0;}
阅读全文
0 0
原创粉丝点击