ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CSP - J 2020 题解

2021-10-30 19:34:23  阅读:97  来源: 互联网

标签:return int 题解 ll dfs 2020 include CSP dp


T1

题目大意

给一个数 $N$, 将其拆分为 $2^x + 2^y + \cdots + 2^z$ 的形式,满足 x < y < z, 输出这些 $2^x$, $2^y$$\cdots 2^z$。

如何解???

反正橙题就是水水水。

不需要证明就可以看出来任意一个偶数的是可以拆分为这个形式的,而 INT_MAX 等于 2 的 31 次方减一,所以打个表暴力就过了。

奇数直接输出 $-1$ 就可以了;

#include <bits/stdc++.h>
#define N 10000
using namespace std;
int n, a[N] = {2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824};
int main(){
	scanf("%d",&n);
	if(n&1){
		printf("-1");
		return 0;
	}
	for(int i=29;i >= 0;i--){
		if(n>=a[i]){
			n-=a[i];
			printf("%d ",a[i]);
		}
	}
	return 0;	
}

T2

不难发现选手的分数都是少于 600 的,我们需要用排序的算法实现这个题,所以桶排是最好的方法, 然后只用一个桶排 + 模拟就过了。

#include <bits/stdc++.h>
#define N 610
using namespace std;
int a[N];
int n,w;
int main(){
	scanf("%d%d",&n,&w);
	for(int i=1,t;i<=n;i++){
		scanf("%d",&t);
//		printf("a[600]=%d\n",a[600]);
		int sv=max(1,w*i/100);
		a[t]++;
//		printf("a[%d]=%d\n",t,a[t]);
//		printf("%d ",sv);
		for(int j=600;j>=0;j--){
			sv-=a[j];
			if(sv<=0){
				printf("%d ",j);
				break;
			}
		}
	}
	
	
	return 0;
}

T3

本题考查的是后缀表达式和树。

叶子节点表示值,根节点表示符号,DFS遍历一遍就可以得到答案了。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int N = 1000010;

char op[N];
int n, m;
int w[N],stk[N],top;
int h[N],e[N],ne[N],idx;
bool st[N];
string s;
void add(int a,int b){e[idx]=b,ne[idx]=h[a],h[a]=idx ++;}
//树上遍历 
int dfs1(int u){
    if(u<=n) return w[u]; 
    //取反 
    if(op[u]=='!') return w[u]=!dfs1(e[h[u]]);
    else if(op[u]=='&'){
    	//与运算 
        w[u]=1;
        for(int i=h[u];~i;i=ne[i])w[u]&=dfs1(e[i]);
        return w[u];
    }
    else{
    	//或运算 
        w[u]=0;
        for(int i=h[u];~i;i=ne[i])w[u]|=dfs1(e[i]);
        return w[u];
    }
}
//更新根节点 
void dfs2(int u){
    st[u]=true;
    if(u<=n) return ;
    if(op[u]=='!') dfs2(e[h[u]]);
    else{
        int a=e[h[u]],b=e[ne[h[u]]];
        if(op[u]=='&'){
            if(w[a]==1) dfs2(b);
            if(w[b]==1) dfs2(a);
        }
        if(op[u]=='|'){
            if(w[a]==0) dfs2(b);
            if(w[b]==0) dfs2(a);
        }
    }
}

int main(){
    getline(cin, s);    
    cin>>n;
    for(int i=1;i<=n;i++) scanf("%d", &w[i]);    
    m=n;     
    memset(h,-1,sizeof(h));
    for(int i=0;i<s.size();i++){
        if(s[i]=='x'){
            i++;
            int k=0;
            while(s[i]>='0'&&s[i]<='9'){ 
                k=k*10+s[i]-'0';
                i++;
            }
            stk[++top] = k;
        }
        else if(s[i]=='!'){            
            op[++m]=s[i];
            int a=stk[top--];
            add(m,a);
            stk[++top]=m;         
            i++;
        }
        else{
            op[++m]=s[i]; 
            int a=stk[top--];
            int b=stk[top--];
            add(m,a),add(m,b);
            stk[++top]= m;         
            i++;
        }
    }
    int root=stk[top];
    int res=dfs1(root);
    //原值 
    dfs2(root);
    int q;
    scanf("%d",&q);
    while(q--){
        int k;
        scanf("%d",&k);
        if(st[k]) printf("%d\n",!res);
        else printf("%d\n",res);
    }
    
    return 0;
}

T4

使用DFS,用记忆化数组优化一下就可以了。

#include <bits/stdc++.h>
#define ll long long
using namespace std;
int n,m;int a[1010][1010];
const ll INF = -100000000000;
ll dp[1010][1010][3];
ll dfs(int x,int y,int z){
	if(x==1&&y==1) return a[1][1];
	if(x<1||x>n||y<1||y>m) return INF;
	if(dp[x][y][z] != INF) return dp[x][y][z];
	if(z==0) return dp[x][y][z]=max(max(dfs(x-1,y,2),dfs(x+1,y,1)),dfs(x,y-1,0))+a[x][y];
	else if(z==1)return dp[x][y][z]=max(dfs(x,y-1,0),dfs(x+1,y,1))+a[x][y];
	else  return dp[x][y][z]=max(dfs(x-1,y,2),dfs(x,y-1,0))+a[x][y];
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			scanf("%d",&a[i][j]), dp[i][j][0] = dp[i][j][1] = dp[i][j][2] = INF;
	printf("%lld",dfs(n,m,0));
	return 0;
}

标签:return,int,题解,ll,dfs,2020,include,CSP,dp
来源: https://www.cnblogs.com/Zheng-XiangYu/p/15486992.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有