csp-j2019,2020,2021,2022复赛答案

2019:

公交换乘

#include <bits/stdc++.h>
using namespace std ;
long long n ;
long long g[100010] , p[100010] , t[100010] ;
long long sum = 0 ;
long long ques = 0 ;
int main(){
	queue<long long>q1 ;
	queue<long long>q2 ;
	cin >> n ;
	for ( int i = 1 ; i <= n ; i++ ){
		cin >> g[i] >> p[i] >> t[i] ;
		if ( g[i] == 0 ){
			sum += p[i] ;
			q1.push(t[i]) ;
			q2.push(p[i]) ;
			ques++ ;
		}
		while ( t[i] - q1.front() > 45 && !q1.empty() ){
			q1.pop() ;
			q2.pop() ;
			ques-- ;
		}
		long long f = 0 ;
		long long quesd = ques ;
		if ( g[i] == 1 ){
			if ( !q1.empty() ){
				for ( int j = 1 ; j <= quesd ; j++ ){
					if ( f == 0 && p[i] <= q2.front() ){
						f = 1 ;
						q1.pop() ;
						q2.pop() ;
						ques-- ;
					}
					else{
						q1.push(q1.front()) ;
						q2.push(q2.front()) ;
						q1.pop() ;
						q2.pop() ;
					}
				}
			}
			else{
				sum += p[i] ;
				continue ;
			}
			if ( f == 0 ){
				sum += p[i] ;
			}
		}
	}
	cout << sum ;
	return 0 ;
}

纪念品

#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int T,n,m,a[105][105],dp[10005];
int main(){
	scanf("%d %d %d",&T,&n,&m);
	for(int i=1;i<=T;i++){
		for(int j=1;j<=n;j++){
			scanf("%d",&a[i][j]);
		}
	}
	for(int i=1;i<T;i++){
		memset(dp,0,sizeof(dp));
		for(int j=1;j<=n;j++){
			for(int k=a[i][j];k<=m;k++){
				dp[k]=max(dp[k],dp[k-a[i][j]]+a[i+1][j]-a[i][j]);
			}
		}
		m+=dp[m];
	}
	cout<<m;
}

加工零件

#include <bits/stdc++.h>
using namespace std;

const int MAXN=1e5+5;
int vex[MAXN],k,n,m,q;
struct edge {
	int u,v,next;
} e[MAXN*2];

int vis[MAXN][2],dis[MAXN][2],que[MAXN*10],q2[MAXN*10],head,rear;

void add(int u,int v) {
	k++;
	e[k].u=u;
	e[k].v=v;
	e[k].next=vex[u];
	vex[u]=k;
}

void SPFA() {
	for(int i=1; i<=n; i++) dis[i][0]=dis[i][1]=1e9;
	dis[1][0]=0;
	head=1;
	rear=0;
	que[++rear]=1;
	while(head<=rear) {
		int u=que[head];
		int t=q2[head];
		head++;
		vis[u][t]=0;
		for(int i=vex[u]; i; i=e[i].next) {
			int v=e[i].v;
			if(dis[v][0]>dis[u][1]+1) {
				dis[v][0]=dis[u][1]+1;
				if(!vis[v][0]) {
					vis[v][0]=1;
					que[++rear]=v;
					q2[rear]=0;
				}
			}
			if(dis[v][1]>dis[u][0]+1) {
				dis[v][1]=dis[u][0]+1;
				if(!vis[v][1]) {
					vis[v][1]=1;
					que[++rear]=v;
					q2[rear]=1;
				}
			}
		}
	}
	return;
}

int main() {
	cin>>n>>m>>q;
	while(m--) {
		int u,v;
		cin>>u>>v;
		add(u,v);
		add(v,u);
	}
	SPFA();
	if(vex[1]==0) dis[1][0]=1e9;
    
	while(q--) {
		int u,L;
		cin>>u>>L;
		if(L>=dis[u][L%2]) cout<<"Yes"<<endl;
		else cout<<"No"<<endl;
	}
	return 0;
}

数字游戏

#include<bits/stdc++.h>
using namespace std;
int main(){
	string a;
	int l = 0;
	cin>>a;
	for(int i = 0;i<a.size();i++){
		if(a[i]=='1'){
			l++;
		}
	}
	cout<<l;
	return 0;
}

2020:

优秀的拆分

#include<bits/stdc++.h>
using namespace std;
int n;
long long a[30];
int main(){
	cin>>n;
	if(n%2==1){
		cout<<"-1";
		return 0;
	}
	a[1]=1;
	for(int i=2;i<=29;i++){
		a[i]=a[i-1]*2;
	}
	for(int i=29;i>=2;i--){
		if(n>=a[i]){
			n-=a[i];
			cout<<a[i]<<' ';
		}
		if(n==0)return 0;
	}
	return 0;
} 

方格取数

#include <stdio.h>
typedef long long LL;
const LL min_ll = -1e18;
int n, m; LL w[1005][1005], f[1005][1005][2];
inline LL mx(LL p, LL q, LL r) {return p > q ? (p > r ? p : r) : (q > r ? q : r);}
inline LL dfs(int x, int y, int from) {
    if (x < 1 || x > n || y < 1 || y > m) return min_ll;
    if (f[x][y][from] != min_ll) return f[x][y][from];
    if (from == 0) f[x][y][from] = mx(dfs(x + 1, y, 0), dfs(x, y - 1, 0), dfs(x, y - 1, 1)) + w[x][y];
    else f[x][y][from] = mx(dfs(x - 1, y, 1), dfs(x, y - 1, 0), dfs(x, y - 1, 1)) + w[x][y];
    return f[x][y][from];
}
int main(void) {
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= m; ++j) {
			scanf("%lld", &w[i][j]);
			f[i][j][0] = f[i][j][1] = min_ll;
		}
    f[1][1][0] = f[1][1][1] = w[1][1];
	printf("%lld\n", dfs(n, m, 1));
	return 0;
}

直播获奖

#include<bits/stdc++.h>
using namespace std;
int a[100004];
priority_queue<int,vector<int>,greater<int> >q;
priority_queue<int>p;
int sca()
{
    int s=0,w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
        w=ch=='-'?-1:w,ch=getchar();
    while(ch>='0'&&ch<='9')
        s=s*10+ch-'0',ch=getchar();
    return s*w; 
}
int main()
{
    int b,n,num;
    n=sca();b=sca();
    for(int i=1; i<=n; i++)
    {

        a[i]=sca();num=max(1,i*b/100);
        if(q.size()<num)
        {
            if(p.empty())
                q.push(a[i]);
            else
            {
                if(p.top()<a[i])
                    q.push(a[i]);
                else
                    q.push(p.top()),p.pop(),p.push(a[i]);
            }
        }
        else
        {
            while(q.top()<a[i]&&(int)q.size()>=num)
                p.push(q.top()),q.pop();
            if(q.size()<num)
                q.push(a[i]);
            else
                p.push(a[i]);
        }
        printf("%d%c",q.top(),i==n?'\n':' ');
    }
    return 0;
}

表达式

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <map>
using namespace std;
const int N=1000100;
int n,m,i,t,t1,len,mp[N],z[N],res1,a[N],p,k;
char c[N];
struct Node 
{
	int z,y,res,fh;   
}jd[1000100];
void tree(int x)
{
	if (jd[x].fh==-1)
	 mp[jd[x].z]=1;
    else
     {
     	if (jd[jd[x].z].res^jd[x].fh) tree(jd[x].y);
     	if (jd[jd[x].y].res^jd[x].fh) tree(jd[x].z);
	 }
    return;
} 
int sz(int x)
{
	int m=0;
	while (c[x]>='0'&&c[x]<='9') 
	 m=m*10+(c[x]-48),x=x+1;
	 return m;
}
 int main()
 {
    gets(c);
    len=strlen(c);
    scanf("%d",&n);
     for (i=1;i<=n;i++)
      scanf("%d",&a[i]);
     t=0;
     t1=0;
      for (i=0;i<=len-1;i++)
       if (c[i]=='x')
        {
        	k=sz(i+1);
        	jd[++t].res=a[k];
        	jd[t].fh=-1;
        	jd[t].z=k;
        	jd[t].y=k;
        	z[++t1]=t;
		}
		else
	    if (c[i]=='&')
	    {
	    	jd[++t].fh=0;
	    	jd[t].y=z[t1];
	    	jd[t].z=z[--t1];
	    	jd[t].res=(jd[jd[t].y].res)&&(jd[jd[t].z].res);
	    	z[t1]=t;
		}
		else
		if (c[i]=='|')
		{
	    	jd[++t].fh=1;
	    	jd[t].y=z[t1];
	    	jd[t].z=z[--t1];
	    	jd[t].res=(jd[jd[t].y].res)||(jd[jd[t].z].res);
	    	z[t1]=t;
		}
		else
		if (c[i]=='!')
	    	jd[z[t1]].res=!(jd[z[t1]].res);
		res1=jd[t].res;
		memset(mp,0,sizeof(mp)); 
		tree(t);
	  scanf("%d",&m);
	   for (i=1;i<=m;i++)
	    {
	    	scanf("%d",&p);
	    	if (mp[p]==1)
	    	 printf("%d\n",!res1);
	    	 else
	    	 printf("%d\n",res1);
		}
      return 0;
  }

2021:

插入排序

#include<bits/stdc++.h>
using namespace std;
int n,q,a[8005],b[8005],num,x,v,ans;
int main()
{
	scanf("%d%d",&n,&q);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=i;j++)
		{
			if(i==j||a[j]<a[i]||a[j]==a[i])b[i]++;
			else b[j]++;
		}
	}
	for(int i=0;i<q;i++)
	{
		scanf("%d",&num);
		if(num==1)
		{
			scanf("%d%d",&x,&v);
			for(int i=1;i<=n;i++)
			{
				if(i==x)continue;
				if((a[i]<a[x]||a[i]==a[x]&&i<x)&&(a[i]>v||a[i]==v&&i>x))
				{
					b[i]++;b[x]--;
				}
				else if((a[i]>a[x]||a[i]==a[x]&&i>x)&&(a[i]<v||a[i]==v&&i<x))
				{
					b[i]--;b[x]++;
				}
			}
			a[x]=v;
		}
		if(num==2)
		{
			scanf("%d",&x);
			printf("%d\n",b[x]);
		}
	}
	return 0;
}

分糖果

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

int n,l,r;

int main(){
	cin>>n>>l>>r;
	if(l/n==r/n) cout<<r%n;
	else cout<<n-1;
	return 0;
}

网络连接

#include <bits/stdc++.h>
using namespace std;
int n;
bool Check(string s) {
  long long a, b, c, d, port;
  if (sscanf(s.c_str(), "%lld.%lld.%lld.%lld:%lld", &a, &b, &c, &d, &port) != 5)  return false;
  if (a < 0 || a > 255 || b < 0 || b > 255 || c < 0 || c > 255 || d < 0 || d > 255 || port < 0 || port > 65535)  return false;
  stringstream ss;
  ss << a << '.' << b << '.' << c << '.' << d << ':' << port;
  return ss.str() == s;
}
map<string, int> mp;
string op, ad;
int main() {
  cin >> n;
  for (int i = 1; i <= n; i++) {
    cin >> op >> ad;
    if (!Check(ad)) { cout << "ERR\n"; continue; }
    if (op[0] == 'S') {
      if (mp[ad]) cout << "FAIL\n";
      else mp[ad] = i, cout << "OK\n";
    } else {
      if (!mp.count(ad)) cout << "FAIL\n";
      else cout << mp[ad] << '\n';
    }
  }
  return 0;
}

小熊的果篮

#include<bits/stdc++.h>
using namespace std;
int n,a[200005],b[200005],t[200005],hd[200005],hd2[200005],nxt[200005],fa[200005],sum,cnt,c,ttt;
int find(int i) {
	if(fa[i]!=i) return fa[i]=find(fa[i]);
	return i;
}
void merge(int x,int y) {
	x=find(x),y=find(y);
	if(x>y) swap(x,y);
	fa[x]=y;
}
int main() {
	scanf("%d",&n);
	for(int i=1;i<=n;++i)
		scanf("%d",&a[i]),fa[i]=i;
	++cnt;
	b[1]=1,hd[1]=1;
	for(int i=2;i<=n;++i) {
		if(a[i]!=a[i-1]) ++cnt,hd[cnt]=i;
		++b[cnt];
	}
	while(sum<n) {
		for(int i=1;i<cnt;++i) printf("%d ",hd[i]),merge(hd[i]-1,hd[i]);
		printf("%d\n",hd[cnt]);
		merge(hd[cnt]-1,hd[cnt]);
		sum+=cnt;
		c=0;
		ttt=0;
		for(int i=1;i<=cnt;++i) {
			if(b[i]>1) {
				if(b[i-1]>1||c==0||ttt%2==0) ++c,hd2[c]=find(hd[i])+1,t[c]=0;
				t[c]+=b[i]-1;
				ttt=0;
			}
			else ++ttt;
		}
		cnt=c;
		for(int i=1;i<=cnt;++i) b[i]=t[i],hd[i]=hd2[i];
	}
	return 0;
}

2022:

乘方

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fore(i,x,n) for(int i=x;i<=n;i++)   
const int MAXANS=1000000000;
int a,b;
inline int Pow(int x,int y){
    int res=1;
    while(y){
        if(y&1) res*=x;
        if(res>MAXANS||res<=0) return -1;
        y>>=1; x*=x;
    }
    return res;
}
inline void work(){
    if(a>MAXANS){ cout<<-1; return; }
    cout<<Pow(a,b);
}

signed main(){
    cin>>a>>b; 
    work();
}

解密

#include<bits/stdc++.h>
using namespace std;
int main(){
    long long k;
    scanf("%lld",&k);
    while(k--) {
        long long n,e,d;
        scanf("%lld%lld%lld",&n,&e,&d);
        long long PsubQ = sqrt((n - e * d + 2) * (n - e * d + 2) - (n << 2));
        long long PaddQ = n - e * d + 2;
        long long P = (PsubQ + PaddQ) >> 1;
        long long Q = (n - e * d + 2 - (long long)sqrt((n - e * d + 2) * (n - e * d + 2) - 4 * n)) / 2;
        if(P * Q == n && e * d == (P - 1) * (Q - 1) + 1 && P && Q) {
            printf("%lld %lld\n",min(P, Q),max(P, Q));
        }
		else{
            printf("NO\n");
        }
    }
    return 0;
}

逻辑表达式

#include <bits/stdc++.h>
using namespace std;
char str[(int)1e6 + 1];
int c1[(int)1e6 + 1],c2[(int)1e6 + 1],l1[(int)1e6 + 1],l2[(int)1e6 + 1],cnt1,cnt2;
int dfs(int l,int r) {
    if (c1[r] >= l) {
        int ans = dfs(l, c1[r] - 1);
        if (ans == 1) {
            ++cnt1;
            return 1;
        }
        return (ans | dfs(c1[r] + 1, r));
    }
    if (c2[r] >= l) {
        int ans = dfs(l, c2[r] - 1);
        if (ans == 0) {
            ++cnt2;
            return 0;
        }
        return (ans & dfs(c2[r] + 1, r));
    }
    if (str[l] == '(' && str[r] == ')') {
        return dfs(l + 1, r - 1);
    }
    return str[l] - '0';
}
int main(){
    scanf("%s",str + 1);
    int len = strlen(str + 1),x = 0;
    for (int i = 1; i<=len; ++i) {
        if (str[i] == '(') {
            ++x;
        }else if (str[i] == ')') {
            --x;
        }else if (str[i] == '|') {
            l1[x] = i;
        }else if (str[i] == '&') {
            l2[x] = i;
        }
        c1[i] = l1[x];
        c2[i] = l2[x];
    }
    int ans = dfs(1, len);
    printf("%d\n%d %d\n",ans,cnt2,cnt1);
    return 0;
}

上升点列

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

const int N = 510, K = 110;

struct Dot {
    int x, y;
} d[N];

int n, k, ans;
int f[N][K];

bool cmp(Dot a, Dot b) {
    if (a.x != b.x) return a.x < b.x;
    return a.y < b.y;
}

int main() {
    scanf("%d%d", &n, &k);
    for (int i = 1; i <= n; ++i) {
        int x, y;
        scanf("%d%d", &d[i].x, &d[i].y);
    }
    sort(d+1, d+n+1, cmp);
    for (int i = 1; i <= n; ++i) {
        for (int j = 0; j <= k; ++j)
            f[i][j] = j+1;
    }
    for (int i = 2; i <= n; ++i) {
        for (int t = 1; t < i; ++t) {
            if (d[t].y > d[i].y) continue;

            int p = d[i].x - d[t].x + d[i].y - d[t].y - 1;
            for (int j = 0; j <= k; ++j) {
                if (j >= p) f[i][j] = max(f[i][j], f[t][j-p]+p+1);
                else f[i][j] = max(f[i][j], j+1);
            }
        }
    }

    for (int i = 1; i <= n; ++i) ans = max(ans, f[i][k]);
    printf("%d\n", ans);
    return 0;
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值