第十五届中北大学算法与程序设计竞赛【5大AC绿最高题】

问题A:俄罗斯方块
题目描述
玩一个简化版的俄罗斯方块,只有10x10大小的二维平面,且只有四种图案,不会翻转,一行满后不消除,四种图案对应四个编号1,2,3,4,现在给出你所有图案按照先后顺序的下落坐标,你可以将最后的样子输出吗?
注:一个点处如果有方块存在则表示成1,否则为0,也即最后输出一个10x10的01矩阵。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
输入描述:
第一行输入一个正整数n,表示接下来有n个图案落下,保证0<=n<=10。
接下来n行,每行两个数字id,x。
id表示图案的种类,保证1<=id<=4。
x表示图案的左下角所在的横坐标。
保证数据合法,不会出现超出10x10边界的情况。

输出描述:
输出一个10x10大小的矩阵表示最后的形状,保证输出的图案一定可以放在10x10的矩阵中。

输入
3
4 1
1 4
2 1

输出
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
1 1 1 0 0 0 0 0 0 0
0 1 0 1 1 0 0 0 0 0
1 1 1 1 1 0 0 0 0 0

#include <bits/stdc++.h>
using namespace std;
int a[11][11]; 
int n,k,type,loc;

void check1(int loc)
{
	for(int i=9;i>=0;i--)
	{
		if(a[i][loc]==1 || a[i][loc+1]==1)
		{
			a[i+1][loc]=a[i+1][loc+1]=a[i+2][loc]=a[i+2][loc+1]=1;
			return;
		}
	}
	return;
}

void check2(int loc)
{
	for(int i=9;i>=0;i--)
	{
		if(a[i][loc]==1 || a[i][loc+1]==1 || a[i][loc+2]==1 )
		{
			a[i+1][loc]=a[i+1][loc+1]=a[i+2][loc]=a[i+1][loc+2]=1;
			return;
		}
	}
	return;
}

void check3(int loc)
{
	for(int i=9;i>=0;i--)
	{
		if(a[i][loc]==1 || a[i][loc+1]==1 || a[i][loc+2]==1 || a[i][loc+3]==1 )
		{
			a[i+1][loc]=a[i+1][loc+1]=a[i+1][loc+2]=a[i+1][loc+3]=1;
			return;
		}
	}
	return;
}

void check4(int loc)
{
	for(int i=9;i>=0;i--)
	{
		if(a[i][loc]==1 || a[i][loc+1]==1 || a[i][loc+2]==1)
		{
			a[i+1][loc]=a[i+1][loc+1]=a[i+1][loc+2]=a[i+2][loc+1]=1;
			return;
		}
	}
	return;
}

int main()
{
	cin>>n;
	memset(a,0,sizeof(a));
	for(int i=1;i<=10;i++) a[0][i]=1;
	
	while(n--)
	{
		cin>>type>>loc;
		if(type==1)	check1(loc);
		else if(type==2)  check2(loc);
		else if(type==3)  check3(loc);
		else if(type==4)  check4(loc);
	}
	
	for(int i=10;i>=1;i--)
	{
		cout<<a[i][1];
		for(int j=2;j<=10;j++)	cout<<" "<<a[i][j];
		cout<<endl;
	}
	return 0;
}

问题B:真的是签到题
题目描述
本题没有任何输入,请你输出
NUC2020!!!
NUC2020!!!
NUC2020!!!

输入描述:

输出描述:
NUC2020!!!
NUC2020!!!
NUC2020!!!

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

int main()
{
	char c[]="NUC2020!!!";
	for(int i=1;i<=3;i++){
		printf("%s\n",c);
	}
	return 0;
}

问题E:简单的线性代数

题目描述
已知A是一个n阶方阵,且A^k=0,
E是一个n阶单位矩阵,求(E+A+A^2+ ……+A^k-1)的逆

输入描述:
第一行输入两个正整数n,k,表示矩阵的阶数和幂。2<=n<=1000,k<=1e18

接下来n行,读入矩阵A,每个数为int类型整数
输出描述:
一个矩阵,表示(E+A+A^2+ ……+A^k-1)的逆

输入
3 4
1 2 3
1 -2 1
7 -26 1

输出
0 -2 -3
-1 3 -1
-7 26 0

#include <bits/stdc++.h>
#define ll long long 
using namespace std;
  
ll m;
int n, a[1005][1005];
  
int main()
{
    scanf("%d%lld",&n,&m);
    for(int i=1; i<=n; i++)
        for(int j=1; j<=n; j++)  scanf("%d",&a[i][j]);
         
    for(int i=1; i<=n; i++) a[i][i]--;
     
    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( n<=10^{10} )找到最小的某个数据 ans (ans >9)
要求 ans 的每一数位(个位 十位 百位 千位…) 乘积与n相等, 不存在输出-1
PS:多组输入,输入直到文件结束

输入描述:
输入一个小于等于10^{10} 的数正整数n

输出描述:
如果可以找到 某个数据 ans 数位乘积与 n 相等 那么便输出 ans
否则输出 -1

输入
100
12

输出
455
26

说明
4x5x5 = 100
2x6 = 12

#include <bits/stdc++.h>
#define ll long long 
using namespace std;
 
int a[5]={0,2,3,5,7}, num[5], b[10005], ans[10005];
ll n;
 
int main()
{
    while(scanf("%lld", &n) == 1)
	{
        if(n < 10)
		{
            printf("1%lld\n", n);
            continue;
        }
        
        for (int i=1; i<=4; i++)
		{
            num[i]=0;
            while(n%a[i]==0) num[i]++, n/=a[i];
        }
        
        if(n > 1)
		{
            printf("-1\n");
            continue;
        }
        
        int cnt = 0;
        for(int i=1; i<=num[1]/3; i++) ans[cnt++]=8;
        num[1] %= 3;
        for(int i=1; i<=num[2]/2; i++) ans[cnt++]=9;
        num[2] %= 2;
        
        if(num[2] && num[1]) num[2]--, num[1]--, ans[cnt++] = 6;
        if(num[2]) ans[cnt++] = 3;
        if(num[1] > 1) ans[cnt++] = 4, num[1] -= 2;
        if(num[1]) ans[cnt++] = 2;
        
        for(int i=1; i<=num[3]; i++) ans[cnt++] = 5;
        for(int i=1; i<=num[4]; i++) ans[cnt++] = 7;
        
        sort(ans, ans + cnt);
        for(int i=0; i<cnt; i++) printf("%d", ans[i]);
        printf("\n");
    }
 
    return 0;
}

问题H:数位操作2
题目描述
给了你一个极端大的数据集合的信息
N, SUM, X 如下

  1. 这个数据集合里面的N位, 每一数位求和之后刚好等于SUM (比如四位数 1234 数位求和之后是 10);
  2. 它们都有N位, 十进制的(每一位都在0~9), 我们这里降低点难度, 特别容许前导0的存在. 1234, 0123 都是合理的数;
  3. 这N位长度的数字字符串, 任意连续的三位数字构成的数据都能被X整除.
    PS: 有可能 有空数据集

现在输出所有的数据是不可能了,
为了减低难度你只要求出原来数据集合内有多少数据 mod 1000009 就好

输入描述:
N(3 <= N <= 50), SUM,X(1 <= X <= 999);

输出描述:
对满足以上数据个数 取 mod 1000009

输入
4 3 3

输出
6

说明
3000
0300
0030
0003
0120
0210

#include <bits/stdc++.h>
using namespace std;
const int mod = 1000009;
 
int n,sum,m,i,j,k,v,res;
int dp[55][10][10][505];
 
int main()
{
    scanf("%d%d%d",&n,&sum,&m);
    
    if(sum > n*9){
        printf("0\n");
        return 0;
    }
    
    for(i=0; i<10; i++)
        for(j=0; j<10; j++)  dp[2][i][j][i+j] = 1;
    
    for(i=3; i<=n; i++)
        for(j=0; j<10; j++)
            for(k=0; k<10; k++)
                for(v=0; v<10; v++)
		        {
                    int num=j*100 + k*10 + v;
                    if(num%m) continue;
                    for (res=j+k+v; res<=sum; res++)
			        {
                        dp[i][j][k][res] += dp[i-1][k][v][res-j];
                        dp[i][j][k][res] %= mod;
                    }
                }

    int ans=0;
    for(i=0; i<10; i++)
        for(j=0; j<10; j++)  ans = (ans + dp[n][i][j][sum]) % mod;
    
    printf("%d\n", ans);
    return 0;
}

问题K:签个到

在这里插入图片描述
输入
2 1
2 1

输出
3

说明在这里插入图片描述

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

ll n,m;

struct yz{
    long long w,loc;
}a[100001];

bool cmp(yz x,yz y){
    return x.w<y.w;
}

int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>a[i].w;
        a[i].loc=i;
    }
    
    if(n==1){
        cout<<0<<endl;
        return 0;
    }
    
    sort(a+1,a+1+n,cmp);
    
    ll ans=abs(a[n].w-(a[1].w-m*a[1].loc));
    ans=max(ans,abs(a[n].w+a[n].loc*m-a[1].w));
    
    for(int i=2;i<n;i++)
    {
        ll w1=abs(a[i].w+m*a[i].loc-a[1].w);
        ll w2=abs(a[i].w+m*a[i].loc-a[n].w);
        w1=max(w1,w2);
         
        ll w3=abs(a[i].w-m*a[i].loc-a[1].w);
        ll w4=abs(a[i].w-m*a[i].loc-a[n].w);
        w3=max(w3,w4);
        
        ans=max(ans,w1);
        ans=max(ans,w3);
    }
    
    cout<<ans<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

米莱虾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值