第十五届中北大学算法与程序设计竞赛(公开赛)


比赛入口

A - 俄罗斯方块(模拟)

用数组c[] 表示每一列能放方块的最大值(从下往上放的,所以从大到小),然后就是ctrl c + ctrl v的复制粘贴模拟。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <queue>
#include <map>
#include <vector>
#include <algorithm>
typedef long long ll ;
using namespace std ;
const int N = 20 ;
const ll mod=1e9+7 ;
int g[N][N] ,c[N];
int main(){
    int n; scanf("%d",&n) ;
    for(int i=1 ; i<=10 ; ++i)   c[i]=10 ;
    for(int i=1 ; i<=n; ++i){
        int x,y; scanf("%d%d",&x,&y) ;
        if(x==1){
            int j=min(c[y],c[y+1]) ;
            g[j][y]=1 , g[j][y+1]=1 ;
            g[j-1][y]=1 , g[j-1][y+1]=1 ;
            c[y]=min(c[y],j-2) , c[y+1]=min(c[y+1],j-2) ;
        }
        else if(x==2){
            int j=min(c[y],min(c[y+1],c[y+2])) ;
            g[j][y]=1 , g[j][y+1]=1 , g[j][y+2]=1 ;
            g[j-1][y]=1 ;
            c[y]=min(c[y],j-2) ;
            c[y+1]=min(c[y+1],j-1) , c[y+2]=min(c[y+2],j-1) ; 
        }
        else if(x==3){
            int j=min(min(c[y],c[y+1]),min(c[y+2],c[y+3])) ;
            g[j][y]=1 , g[j][y+1]=1 , g[j][y+2]=1 , g[j][y+3]=1 ;
            c[y]=min(c[y],j-1) , c[y+1]=min(c[y+1],j-1) ;
            c[y+2]=min(c[y+2],j-1) , c[y+3]=min(c[y+3],j-1) ;
        }
        else if(x==4){
            int j=min(c[y],min(c[y+1],c[y+2])) ;
            g[j][y]=1 , g[j][y+1]=1 , g[j][y+2]=1 ;
            g[j-1][y+1]=1 ;
            c[y]=min(c[y],j-1) , c[y+1]=min(c[y+1],j-2) ;
            c[y+2]=min(c[y+2],j-1) ;
        }
    }
    for(int i=1 ; i<=10 ; ++i){
        for(int j=1 ; j<=10 ; ++j)
            printf("%d ",g[i][j]) ;
        printf("\n") ;
    }
    return 0 ;
}

B - 签到题

真 签到题哈哈哈哈哈哈

C - 港口(差分)*

如果全部重量相同,那么数组的差分应该是全为0,所以要想办法把差分数组变为0,差分数组 [i,j] 加1 就是 ++subi , --subj+1 ; 减1 就是 --subi , ++subj+1 ,剩下没有为0的就单独变成0 ;
例如:数组7 9 6 5 ,差分数组为 2 -3 -1 ,
那么可以[1,2]减2,差分数组变成: 0 -1 -1 ,现在没有正数了就单独一个变成0 ,需要两次操作,总共4次操作。
所以就是差分数组的正数和 还有 负数和 两者取最大值即可。

#include <cstdio>
#include <cstring> 
#include <iostream>
#include <cmath>
#include <algorithm>
typedef long long ll ; 
using namespace std ;
const int N = 1e5+10 ; 
ll w[N],sub[N] ; 
int main(){
	int n; scanf("%d",&n) ; 
	for(int i=1 ; i<=n ; ++i)	scanf("%lld",&w[i]) , sub[i]=w[i]-w[i-1] ;
	ll x=0 , y=0 ;  
	for(int i=2 ; i<=n ; ++i){
		if(sub[i]>0)	x+=sub[i] ; 
		else	y += -sub[i] ; 	
	}
	printf ("%lld\n",max(x,y)) ; 
	return 0 ; 
}
	

E - 简单的线性代数(数论)- 找规律蒙的

emmmmm这道题,一看以为要用矩阵乘积,但是k却特别大,而且过的人也特别多,然后就看样例猜了一下。。。。。,除了对角线是1-x,其他全部取反。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
typedef long long ll ;
using namespace std ;
const int N = 1010 ;
const ll mod=1e9+7 ;
int a[N][N] ;
int main(){
    int n,k; scanf("%d%d",&n,&k) ;
    for(int i=1 ; i<=n ; ++i){
        for(int j=1 ; j<=n ; ++j){
            scanf("%d",&a[i][j]) ;
            if(i==j)    a[i][j] = 1-a[i][j] ;
            else    a[i][j] = -a[i][j] ;
        }
    }
    for(int i=1 ; i<=n ; ++i){
        for(int j=1 ; j<=n ; ++j)
            printf("%d ",a[i][j]) ;
        printf("\n") ;
    }
    return 0 ;
}

G 数位操作1(模拟)

将n从9->2一直除,结果n=1则将因子排序后输出,如果n<10 那么最小值应该是1n , 其实是道挺简单的题,但是自己粗心忘记考虑n<10的情况(后来考虑到又想错了),然后就WA好几次 TAT

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <queue>
#include <map>
#include <vector>
#include <algorithm>
typedef long long ll ;
using namespace std ;
const int N = 20 ;
const ll mod=1e9+7 ;
vector<ll> ans ;
int main(){
    ll n ;
    while(~scanf("%lld",&n)){
        ans.clear() ;
        if(n<10){
            printf("1%lld\n",n) ;
            continue ;
        }
        for(ll i=9 ; i>=2 ; --i){
            while(n%i==0)   ans.push_back(i),n/=i;
        }
        if(n==1&&ans.size()>1){
            sort(ans.begin(),ans.end()) ;
            for(int i=0 ; i<ans.size() ; ++i)    printf("%lld",ans[i]) ;
            printf("\n") ;
        }  
        else    printf("-1\n") ;
    }
    return 0 ;
}

K - 签个到(思维)- 忘记特判

题解: 先求每个数增加和减少的最大值,然后增加的最大值减去数组的最小值和减少的最大值加上数组的最大值即可,注意n=1时要特判。
哇!气死了气死了气死了,n==1的时候没有特判然后一直WA,哭了,而且还不能在前面特判完return 0(会段错误)┭┮﹏┭┮

#include <cstdio>
#include <cstring> 
#include <iostream>
#include <cmath>
#include <algorithm>
typedef long long ll ; 
using namespace std ;
const int N = 1e6+10 ; 
const ll INF=1e9+7 ;
ll a[N] ;
int main(){
	ll n,m ; scanf("%lld%lld",&n,&m) ;
	ll mx=-INF,amx=-INF,mn=-INF,amn=INF ; 
	for(int i=1 ; i<=n ; ++i){
		scanf("%lld",&a[i]) ;
		if(a[i]>amx)	amx=a[i] ; 
		if(a[i]<amn)	amn=a[i] ; 
		mx=max(mx,a[i]+(ll)i*m) ; 
		mn=max(mn,-a[i]+(ll)i*m) ; 
	}	
    if(n==1)    printf("0\n") ; //特判
	else    printf ("%lld\n",max(mx-amn,mn+amx)) ; 
	return 0 ; 
}
	
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值