牛客月赛58 F(构造) CF824 div2 D(思维)

F
题意:给定一个nn的矩阵,你可以用若干个L型物体来拼好(L型物体,长3宽1),并且特殊要求为,矩阵的左上角22的区域不能放置物体。假设方格编号是(i-1)*n+j,那么输出每个你所用到的L型物体所在的四个方格。

思路:最小的能构成的单元块是两个L拼在一起,构成一个2*4的矩形,那么最优方案就是前两行用这个单元块来横向拼凑,然后接下来的n-2行也用这个单元块来纵向拼凑。

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

const int N = 1e5+100;

int a[N];

signed main()
{
    int n;
    cin>>n;
    if((n-2)%4!=0)
    {
        cout<<-1<<endl;
        return 0;
    }
    cout<<(n*n-2)/4<<endl;
    for(int i=3;i<=n;i+=4)
    {
        cout<<i<<" "<<i+n<<" "<<i+n+1<<" "<<i+n+2<<endl;
        cout<<i+1<<" "<<i+2<<" "<<i+3<<" "<<i+3+n<<endl;
    }
    for(int i=3;i<=n;i+=4)
    {
        for(int j=1;j<=n;j+=2)
        {
            cout<<(i-1)*n+j<<" "<<(i-1)*n+j+1<<" "<<(i-1+1)*n+j<<" "<<(i-1+2)*n+j<<endl;
            cout<<(i-1+1)*n+j+1<<" "<<(i-1+2)*n+j+1<<" "<<(i-1+3)*n+j+1<<" "<<(i-1+3)*n+j<<endl;
        }
    }
    return 0;
}

D

题意:给定n张卡牌,每张卡牌有k个标识符号,每个符号都取0,1,2的三个数中的一个。

现在定义三个并行的标识符号是好的,当且仅当这三个标识符号互不相同或者完全一致。

如果三张卡片的所有对应位置的标识符号都是good的,那么我们称这样的三张卡牌为一个SET

如果五张卡牌中有两个不同的SET,我们就称这五张卡牌为META-SET

先在给定n张卡牌和他们的每一位的标识符号,请你求出这n张卡牌可以组成多少个META-SET

思路:我们知道,一组good标识符号的组成有这样的几种:000 111 222 012等等,但是无一例外,他们的和取模于3都为0,那么如果一组卡牌能够成为SET,我们抽走其中的一张,另外的两张取模于3的余数就应该和被抽走的一张的对应标识符号是相等的。

所以我们n2暴力枚举任意两张卡牌的对应标识符号之和的取模于3的余数,然后根据这个余数来匹配。

我们假设一张卡牌能够匹配cnt对,那么一张卡牌能够满足的META-SET就是C(2,cnt)个。

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1000+100;
map<vector<int>,int> mp;

vector<int> v[N];

signed main()
{

    int n,k;
    cin>>n>>k;
    for(int i=1;i<=n;i++)
    {
        for(int j=1,temp;j<=k;j++)
        {
            cin>>temp;
            v[i].push_back(temp);
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=i+1;j<=n;j++)
        {
            vector<int>temp;
            for(int l=0;l<k;l++)
            {
                temp.push_back((6-v[i][l]-v[j][l])%3);
            }
            mp[temp]++;
        }
    }
    int ans=0;
    for(int i=1,cnt;i<=n;i++)
    {
        cnt=mp[v[i]];
        ans+=(cnt*(cnt-1))/2;
    }
    cout<<ans;
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值