• CSP2020第二轮J组简析


    CSP2020第二轮J组简析

    祝各位NOIPrp++

    T1 优秀的拆分

    **题,奇数-1,偶数从大往小枚举2的次方

    #include<cstdio>
    using namespace std;
    int n,k;
    long long a[30];
    int main()
    {
    	freopen("power.in","r",stdin);
    	freopen("power.out","w",stdout);
    	scanf("%d",&n);
    	if (n%2==1)
    	{
    		printf("-1
    ");
    		fclose(stdin);
    		fclose(stdout);
    		return 0;
    	}
    	a[0]=1;
    	k=0;
    	while (a[k]<=n)
    		a[k+1]=a[k]*2,++k;
    	for (int i=k;i;--i)
    		if (a[i]<=n) printf("%lld ",a[i]),n-=a[i];
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    

    T2 直播获奖

    如果成绩大点是个好题,但是这题成绩最大600,所以……直接上桶

    然鹅我并没有切,原因
    在这里插入图片描述
    没到0呀!!!

    #include<cstdio>
    #include<iostream>
    using namespace std;
    int n,w,x,num,a[605];
    int main()
    {
    	freopen("live.in","r",stdin);
    	freopen("live.out","w",stdout);
    	scanf("%d%d",&n,&w);
    	for (int i=1;i<=n;++i)
    	{
    		scanf("%d",&x);
    		++a[x];
    		num=0;
    		for (int j=600;j>=0;--j)
    		{
    			num+=a[j];
    			if (num>=max(1,i*w/100))
    			{
    				printf("%d ",j);
    				break;
    			}
    		}
    	}
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    

    T3 表达式

    这次比赛最难的一题,比第四题难多了。原本CSP应该是T3dp,T4数据结构/图论,结果今年换了……

    首先先根据读入的字符串建出一个二叉树

    由于(1&x=x,0|x=x),所以这两种情况下(x)的取值可能会影响最后的结果。但是我们知道(0&x=0,1|x=1),所以在这两种情况下(x)的取值就无关紧要了,我们可以在二叉树里递归,然后打上无用标记

    最后询问的时候看一下有没有标记,然后判断是否取反原来的结果

    #include<cstdio>
    #include<cstring>
    #define N 1000005
    using namespace std;
    struct node
    {
    	int res,fh,l,r;
    }tree[N];
    int n,m,len,x,tot,num,ans,a[N],q[N];
    char s[N];
    bool bj[N];
    int number(int x)
    {
    	int res=0;
    	while (s[x]>='0'&&s[x]<='9') res=(res<<1)+(res<<3)+(s[x]-'0'),++x;
    	return res;
    }
    void build(int now)
    {
    	if (tree[now].fh==-1) bj[tree[now].l]=true;
    	else
    	{
    		if (tree[now].fh^tree[tree[now].l].res) build(tree[now].r);
    		if (tree[now].fh^tree[tree[now].r].res) build(tree[now].l);
    	}
    }
    int main()
    {
    	freopen("expr.in","r",stdin);
    	freopen("expr.out","w",stdout);
    	gets(s);
    	len=strlen(s);
    	scanf("%d",&n);
    	for (int i=1;i<=n;++i)
    		scanf("%d",&a[i]);
    	for (int i=0;i<len;++i)
    	{
    		if (s[i]=='x')
    		{
    			x=number(i+1);
    			tree[++tot].res=a[x];
    			tree[tot].l=tree[tot].r=x;
    			tree[tot].fh=-1;
    			q[++num]=tot;
    		}
    		if (s[i]=='&')
    		{
    			tree[++tot].fh=0;
    			tree[tot].l=q[num];
    			tree[tot].r=q[--num];
    			tree[tot].res=(tree[tree[tot].l].res)&(tree[tree[tot].r].res);
    			q[num]=tot;
    		}
    		if (s[i]=='|')
    		{
    			tree[++tot].fh=1;
    			tree[tot].l=q[num];
    			tree[tot].r=q[--num];
    			tree[tot].res=(tree[tree[tot].l].res)|(tree[tree[tot].r].res);
    			q[num]=tot;
    		}
    		if (s[i]=='!') tree[q[num]].res=!(tree[q[num]].res);
    	}
    	ans=tree[tot].res;
    	build(tot);
    	scanf("%d",&m);
    	for (int i=1;i<=m;++i)
    	{
    		scanf("%d",&x);
    		if (bj[x]) printf("%d
    ",!ans);
    		else printf("%d
    ",ans);
    	}
    	fclose(stdin);
    	fclose(stdout);
    	return 0;	
    }
    

    T4 方格取数

    (dp),由于不能往左走,所以按列dp。每个点从3个方向转移,注意要么一直到上,要么一直到下,因为不能重复

    #include<cstdio>
    #include<iostream>
    #define ll long long
    #define inf 2147483600
    using namespace std;
    int n,m,a[1005][1005];
    ll f[1005][1005][5];
    int main()
    {
    	freopen("number.in","r",stdin);
    	freopen("number.out","w",stdout);
    	scanf("%d%d",&n,&m);
    	for (int i=1;i<=n;++i)
    		for (int j=1;j<=m;++j)
    			scanf("%d",&a[i][j]);
    	for (int i=0;i<=n;++i)
    		for (int j=0;j<=m;++j)
    			f[i][j][1]=f[i][j][2]=f[i][j][3]=-inf;
    	f[1][1][1]=f[1][1][2]=f[1][1][3]=a[1][1];
    	for (int j=1;j<=m;++j)
    	{
    		for (int i=1;i<n;++i)
    			f[i+1][j][1]=max(f[i][j][1],f[i][j][3])+a[i+1][j];
    		for (int i=n;i>1;--i)
    			f[i-1][j][2]=max(f[i][j][2],f[i][j][3])+a[i-1][j];
    		for (int i=1;i<=n;++i)
    			f[i][j+1][3]=max(f[i][j][1],max(f[i][j][2],f[i][j][3]))+a[i][j+1];
    	}
    	printf("%lld
    ",max(f[n][m][1],max(f[n][m][2],f[n][m][3])));
    	fclose(stdin);
    	fclose(stdout);
    	return 0;	
    } 
    

    好像有点短……析嘛

  • 相关阅读:
    [Ubuntu]更改所有子文件和子目录所有者权限
    [ubuntu] 外挂硬盘
    HashMap、Hashtable、ConcurrentHashMap的原理与区别
    [Pytorch笔记] scatter_
    [The Annotated Transformer] Iterators
    [python 笔记] __iter__迭代器
    [负数在内存中的存储] 0x80000000 = -2147483648
    [NLP] The Annotated Transformer 代码修正
    [pytorch笔记] 调整网络学习率
    numpy中双冒号的作用
  • 原文地址:https://www.cnblogs.com/H-K-H/p/14086354.html
Copyright © 2020-2023  润新知