2016.8.5测试解题报告(english,chemistry,chiese)

今天的题解写晚了,因为光光是改程序调程序就改到了23:20分这个样子,所以说今天的题解可能会略为的潦草和语无伦次请见谅!

1.英语

怎么说呢…这道题的题意和英语完全不相干啊!我也不知道为什么它叫英语=。=

题意:把石子分成N堆,每次可以取出一个或几个石子(不可以不取),每次取完石子之后可以选择将余下的部分石子分给其他堆(可以不移动),给出石子的数量,请输出是否有先手必胜的策略。

考试的时候我很清楚的记得吴大爷在培训的day9讲过这样一道拓展题,但我干脆就忘了正解是什么了,于是我就写了一份NIM一般游戏的代码(既不用分石子的NIM游戏),居然骗到了90分我非常的开心啊。但是这道题的正解也是非常好想的。

第一个if:对于每一个只有一堆石子的状态,都是一个先手必胜的状态。
第二个if:对于每一个只有两堆石子的状态,同一般NIM游戏的思考方式,异或和为0时先手必败,否则先手必胜。
第三部分:对于每一堆石子,若有一堆石子的数目不为1则先手必胜。

/*
2016.8.5 CHN
*/

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<cstring>
#include<iostream>
using namespace std;
int n;
int x,y;
bool win=0;
int main()
{
    freopen("english.in","r",stdin);
    freopen("english.out","w",stdout);
    while(scanf("%d",&n)==1)
    {
        win=0;
        if(n==1)
        {
            scanf("%d",&x);
            printf("YES\n");
            continue;
        }
        if(n==2)
        {
            scanf("%d%d",&x,&y);
            if(x==y) printf("NO\n");
            else     printf("YES\n");
            continue;
        }
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&x);
            if(x!=1) win=true;
        }
        if(win) printf("YES\n");
        else
        {
            if(!n&1) printf("NO\n");
            else       printf("YES\n");
        }

    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}

2.化学

这道鬼畜的题让我差点就调了一宿过去,本来以为今天晚上是写不了题解了,没想到今天晚上居然精力比较充沛,于是就打算趁热打铁赶紧来一发题解了。

题意:一个由5个田字格拼成十字形组成的棋盘,给出点N并以此给出这N个点的坐标,每次移动棋子的时候必须要满足一下几个条件才能移动:1.每次移动能且仅能向上下左右四个方向移动两个格子。2.每次移动的目标点点目前不能有棋子(棋子不可以累加) 3.每次移动的时候必须是跳过去的而不是走过去的,就是说移动还要满足初始点与目标点的中电必须要有一个棋子。移动后被跨过的棋子被删去。

分析:分析题意我们可以知道:由于每次必须且仅能删除一个点,所以说要走到最后的状态既图中只有一个点的情况时必定只移动了n-1次棋子。我选择了比较好写的dfs进行搜索,因为我们已知深度和决策,可以限制dfs的深度。

易错点:每进行一步操作的时候我们有很多需要改变的东西:改变此次被移动的棋子的坐标,改变存储棋子位置的图,同时记录每一步的横纵坐标和进行的操作的种类。同时还要注意的是,i轴的增加是Down,i轴的减少是Up,j轴的增加为Right,j轴的减少为Left。

优化:这道题如果直接dfs的话肯定没有广搜要优,如何降低其时间复杂度呢?由于在棋盘边缘的点,或者在图块边缘的点进行移动很可能出现无解的情况,所以我们可以从内向外搜,既从图块的内部向外部拓展,这样可以更快更直接的找到可达到的最优解。

(题主实在懒得打注释了,已经是后半夜了,见谅!)

/*
2016.8.5CHN
*/
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<cstring>
#include<iostream>
using namespace std;
struct point
{
    int x,y;
}p[40];
int ans=2147483600;
int a[8][8];
int n;
int tot=0;
int st[500005];
int poi[500005];
int mox[500005];
int moy[500005];
int w[3][5]=
{
    0,0,0,0,0,
    0,2,-2,0,0,
    0,0,0,2,-2,
};
bool cmp(point l,point ll)
{
    return abs(l.x-l.y)<abs(ll.x-ll.y);
}
bool chackpoint(int x,int y)
{
    if(a[x][y]==1) return 0;
    if(x<1 || x>7 || y<1 || y>7) return 0;
    if((x>=3 && x<=5) || (y>=3 && y<=5)) return 1;
    return 0;
}
void dfs(int u,int done,int lastpoint,int step)
{
    //cout<<step<<endl;
    if(step==n-1)
    {
        printf("%d\n",n-1);
        for(int i=1;i<=n-1;i++)
        {
            printf("%d %d\n",mox[i],moy[i]);
            if(st[i]==1) printf("Down\n");
            else if(st[i]==2) printf("Up\n");
            else if(st[i]==3) printf("Right\n");
            else if(st[i]==4) printf("Left\n");
        }
        exit(0);
    }
    if(step>n) return;
    for(int i=n;i>=1;i--)
    {
        for(int k=1;k<=4;k++)
        {
            int px=p[i].x+w[1][k];
            int py=p[i].y+w[2][k];
            int qx=p[i].x+w[1][k]/2;
            int qy=p[i].y+w[2][k]/2;
            if(a[p[i].x][p[i].y] && a[qx][qy] && chackpoint(px,py))
            {
                a[p[i].x][p[i].y]=0;
                a[px][py]=1;
                a[qx][qy]=0;
                mox[++tot]=p[i].x;
                moy[tot]=p[i].y;
                st[tot]=k;
                p[i].x=px;
                p[i].y=py;
                dfs(u-1,k,i,step+1);
                p[i].x=px-w[1][k];
                p[i].y=py-w[2][k];
                a[p[i].x][p[i].y]=1;
                a[px][py]=0;
                a[qx][qy]=1;
                tot--;
            }
        }
    }
}
int main()
{
    freopen("chemistry.in","r",stdin);
    freopen("chemistry.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&p[i].x,&p[i].y);
        a[p[i].x][p[i].y]=1;
    }
    sort(p+1,p+1+n,cmp);
    for(int i=1;i<=n;i++)
    {
        for(int k=1;k<=4;k++)
        {
            int px=p[i].x+w[1][k];
            int py=p[i].y+w[2][k];
            int qx=p[i].x+w[1][k]/2;
            int qy=p[i].y+w[2][k]/2;
            if(a[p[i].x][p[i].y] && a[qx][qy]==1 && chackpoint(px,py))
            {
                a[p[i].x][p[i].y]=0;
                a[px][py]=1;
                a[qx][qy]=0;
                mox[++tot]=p[i].x;
                moy[tot]=p[i].y;
                st[tot]=k;
                p[i].x=px;
                p[i].y=py;
                dfs(n-1,k,i,1);
                p[i].x=px-w[1][k];
                p[i].y=py-w[2][k];
                a[p[i].x][p[i].y]=1;
                a[px][py]=0;
                a[qx][qy]=1;
                tot--;
            }
        }
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}

3.语文

这是一道…逗比题。真是不懂这道题考察的点啊,打一个懒标记并在上传过程中不断得出答案就可以A了这道题,读题加上码码一共耗时5分多钟。可以说数据也是相当的弱鸡了,居然没有出一个极限的长链来卡我….

题意:给你一棵有N个结点的树和每个点的点权值,并让你处理M个操作,操作有两种形式:p i j,既使以i为根的子树中的所有结点(不包括i点)的权值都+j,u i,既查询i点的点权值。

思路:正常建树,每次p操作时,在i点打上懒标记,在每次u操作时向上累加标记,因为i点一定是它每个祖先结点的子树中的点。最后用标记的累加值加上点权值,得出答案。

(这道题的数据有毒,数据与题目藐视完全不符而且逻辑有障碍)

/*
2016.8.5CHN
*/
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<cstring>
#include<iostream>
using namespace std;
int n,m;
int fa[500005];
int lazy[500005];
int val[500005];
int query(int k)
{
    if(k==0) return 0;
    return query(fa[k])+lazy[k];
}
int main()
{
    freopen("stdkiller.in","r",stdin);
    freopen("stdkiller.out","w",stdout);
    scanf("%d%d%d",&n,&m,&val[1]);
    for(int i=2;i<=n;i++) scanf("%d%d",&val[i],&fa[i]);
    for(int k=1;k<=m;k++)
    {
        char c;
        scanf("%c%c",&c,&c);
        if(c=='p')
        {
            int x,y;
            scanf("%d%d",&x,&y);
            lazy[x]+=y;
        }
        if(c=='u')
        {
            int x;
            scanf("%d",&x);
            /*
            printf("%d ",fa[x]);
            cout<<query(0)<<" "<<val[x]<<" ";*/
            printf("%d\n",query(fa[x])+val[x]);
        }
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}

今天的题解更新晚了,对不起各位!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值