SDUT 2022 Spring Team Contest——11(补题)

 题目链接:

Dyson Box - Gym 103118D - Virtual Judge (vjudge.net)

概述:给定方块的坐标,T时间内输出前T个方块下对齐与右对齐之后的边长

思路:

以下对齐为例:

ans表示边长总数

用map存储每个x坐标的个数

对于第一个:ans+=4;

对于后面的方块:ans+=2;(两条边重合,减去)

判断mp[x-1]与mp[x+1]与mp[x]的大小关系

大于等于的话会出现如下情况(以中间方块为例,左右各有两边重合所以需要执行两次ans-=2)

 

 最后输出每一次的ans即可

#include <iostream>
#include <map>
#include <algorithm>
using namespace std;
#define int long long
#define endl '\n'
#define _ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
signed main ()
{
    _
    
    int n;
    cin >> n;
    int ans1=0,ans2=0;
    map<int,int> mx,my;
    while (n -- )
    {
        
        int x,y;
        cin >> x >> y;
        if(!mx[x])
            ans1+=4;
        else
            ans1+=2;
        if(!my[y])
            ans2+=4;
        else
            ans2+=2;
        mx[x]++,my[y]++;
        if(mx[x-1]>=mx[x])
            ans1-=2;
        if(mx[x+1]>=mx[x])
            ans1-=2;
        if(my[y+1]>=my[y])
            ans2-=2;
        if(my[y-1]>=my[y])
            ans2-=2;
        cout << ans1 << " " << ans2 << endl;
    }
    
}

 题目链接:

Adventurer's Guild - Gym 103118H - Virtual Judge (vjudge.net)

题目概述:

给出怪物的数量n,人物血量H,人物的攻击S;
接下来n行,每一行为每只怪物的血量h,攻击s,价值w;

每消灭一个怪物,消耗h的血量和s的攻击,S如果为负数,需要用H去弥补S,如果H为负数则结束;
输出可以获得的最大价值;

思路:

二维费用背包+判断

#include <bits/stdc++.h>
using namespace std;
const int N=1e3+10;
#define int long long
int v1[N],v2[N],f[N][N],w[N];
int n,m,k;
signed main()
{
    cin>>n>>m>>k;
    for (int i=1;i<=n;i++) cin>>v1[i]>>v2[i]>>w[i];
    for (int i=1;i<=n;i++)
        for (int j=m;j>0;j--)//血量
            for (int l=k;l>=0;l--)//耐力
            {
                if (j>v1[i]&&l>=v2[i])
                f[j][l]=max(f[j][l],f[j-v1[i]][l-v2[i]]+w[i]);
                else if (j>v1[i]&&l+j-v1[i]-v2[i]>0)
                f[j][l]=max(f[j][l],f[l+j-v1[i]-v2[i]][0]+w[i]);
            }
    cout<<f[m][k];
    return 0;
}

 

 题目链接:

Matrix Problem - Gym 103118M - Virtual Judge (vjudge.net)

题目概述:

给定二维的矩阵 c,要求当 c 的某处为 1 时,矩阵 a 和 b 的对应位置均为 1 ,否则AB矩阵对应位置不能相同,且矩阵 a 和 b 中的 1 需要连通。

思路:

构造题:

AB矩阵是互相对应的,对应关系是:C矩阵为1的时候AB一定为1 & 否则A矩阵为1B矩阵为0 | A矩阵为0B矩阵为1

如此只要知道A矩阵的值就能推出B矩阵相应的值

对于A矩阵的初始构造可以采用如下方法:(5*5为例)

 

 左侧全部为1右侧全部为0  (B矩阵相应的是左侧全部为0右侧全部为0)

左侧的1仿佛是桥一样能够联通所有的1(题目保证C矩阵最外围一定不会有1)

那么C矩阵的1就会是下面的两种情况

(1):在A矩阵为1的地方出现

(2):在A矩阵为0的地方出现

对于(1)A矩阵无需变换

对于(2):

假设图变成这样

 

 在0那一行的1可以通过上边或下面走到“桥”上实现联通(也就是为什么中间要一行0一行1)

结束

#include <iostream>
#include <map>
#include <algorithm>
using namespace std;
const int N = 510;
#define int long long
#define endl '\n'
#define _ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);

char a[N][N],b[N][N],c[N][N];

signed main ()
{
    _
    int n,m;
    cin >> n >> m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            a[i][j]=b[i][j]='0';//AB矩阵初始化
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin >> c[i][j];
    for(int i=1;i<=n;i++)
    {
        char k='1';
        if(i%2==0)k='0';  //A矩阵中间的地方按行奇偶性分为0和1
        for(int j=1;j<=m;j++)
            a[i][j]=k;
    }
    for(int i=1;i<=n;i++)a[i][1]='1',a[i][m]='0';  //初始化左侧和右侧
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(c[i][j]=='1')
                a[i][j]='1'; //改变C矩阵是1且A矩阵为0的地方
        }
    }
    for(int i=1;i<=n;i++)  //对于AC矩阵写出B矩阵的值
    {
        for(int j=1;j<=m;j++)
        {
            if(c[i][j]=='1')
                b[i][j]='1';
            else
            {
                if(a[i][j]=='1')
                    b[i][j]='0';
                else
                    b[i][j]='1';
            }
        }
    }
    for(int i=1;i<=n;i++)   //输出A矩阵
    {
        for(int j=1;j<=m;j++)
            cout << a[i][j];
        cout << endl;
    }
    for(int i=1;i<=n;i++)  //输出B矩阵
    {
        for(int j=1;j<=m;j++)
            cout << b[i][j];
        cout << endl;
    }
}

 

posted @ 2022-05-09 19:48  MrSugarT  阅读(49)  评论(0编辑  收藏  举报