CodeForces 1391总结

传送门
A.Suborrays
描述的花里胡哨,其实就直接打印以个1~n的顺序数组即可。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
#include<cmath>
#include<cstdio>
#include<vector>
#include<queue>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=105;
typedef long long ll;
int t,a[maxn],w,n,q,i,j,k,temp,ans,cnt,sum,index,Max,Min1,Min2,Min;
int arr[100001];
int freq[100001];
int main()
{
    
    
    ios::sync_with_stdio(false);
	cin>>t;
	while(t--)
    {
    
    
        cin>>n;
        for(i=1;i<=n;i++)
            cout<<i<<" ";
        cout<<endl;
    }
	return 0;
}

B.Fix You
给你一个矩阵,在(i,j)点有一个字母R或D代表向右或向下走,现在需要让所有点都可以走到矩阵右下角,问最少需要改几个点。水题,把最右端一列全改成D,最下端一行全改成R(除了最后一个点)即可。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
#include<cmath>
#include<cstdio>
#include<vector>
#include<queue>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=105;
typedef long long ll;
int t,a[maxn],w,n,m,q,i,j,k,temp,ans,cnt,sum,index,Max,Min1,Min2,Min;
char ch[maxn][maxn];
int main()
{
    
    
    ios::sync_with_stdio(false);
    cin>>t;
    while(t--)
    {
    
    
        cin>>m>>n;
        sum=0;
        for(i=1; i<=m; i++)
        {
    
    
            for(j=1; j<=n; j++)
            {
    
    
                cin>>ch[i][j];
                if(j==n&&ch[i][j]=='R')
                    sum++;
                if(i==m&&ch[i][j]=='D')
                    sum++;
            }
        }
        cout<<sum<<endl;
    }
    return 0;
}

C.Cyclic Permutations
一个数列里面包含1~n,一个数字只出现一次且顺序随机,现题目要求找出每个数字前离他最近的比他大的数字和在他后面找出离他最近且比他大的数字的索引值,在中间插上隔板,要使其成为一个循环
以n=4和p=[3,1,4,2]为例;图的边为(1,3)、(2,1)、(2,3)、(4,3)
如果用p建立的图至少有一个简单循环,则置换p是循环的。
解释:

对于p=[3,1,4,2],

-我们做边(1,3),因为3是i=1的最小j。

-我们做边(2,1),因为1是i=2的最大j。

-我们做边(2,3),因为3是i=2的最小j。

-我们做边(4,3),因为3是i=4的最大j

如果满足以下条件,则节点v1、v2、…、vk形成一个简单循环:
1.k≥3
2.对于指数i和j的任何一对,vi≠vj。(1≤i<j≤k)
3.vi和vi+1对所有i(1≤i<k)共享一个边,v1和vk共享一个边。
这个题我看了好久才大概明白意思,到比赛结束也不知道例子是咋来的,云里雾里。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
#include<cmath>
#include<cstdio>
#include<vector>
#include<queue>
#define INF 0x3f3f3f3f
#define mod 1000000007
using namespace std;
const int maxn=105;
typedef long long ll;
ll t,a[maxn],w,n,m,q,i,j,k,temp,ans,cnt,sum,index,Max,Min1,Min2,Min;
char ch[maxn][maxn];
ll multi(ll a, ll b)
{
    
    
	return ((a%mod)*(b%mod))%mod;
}
int main()
{
    
    
    ios::sync_with_stdio(false);
    cin>>n;
    sum=1;
	for(i=2;i<=n;i++)
		sum=multi(sum, i);
	ans=1;
	for(i=1;i<=n-1;i++)
		ans=multi(ans, 2);

	cout<<(sum-ans + mod)%mod<<endl;
    return 0;
}

D. 505
给你一个矩阵,如果每个偶数长度的平方子矩阵都具有奇数个1,则该二进制矩阵称为好矩阵。计算出将其变为好矩阵所需要更改的最小单元数,或输出-1代表无法将其变好。
搜了题解,可以通过暴力枚举,若n>=4,无解,因为当存在 4 * 4 的方阵时,若其四个角的2 * 2 的方阵里的 1 为奇数个,那么4 * 4 里的就一定为偶数个。
剩下的情况分类讨论n=1,n=2,n=3,暴力枚举第一列后,再在满足要求的前提下拓展到第 m 列,过程中记录操作的次数,最后取最小操作次数。
E. Pairs of Pairs
给你一个n个节点和m条边组成的无向图,现需要将结点进行配对,一个结点最多在一个对中,有效对的概念是对于任意两对(a,b)和(c,d),节点为{a,b,c,d}的诱导子图至多有2条边。
现在,执行下列操作之一:
1.找到一条至少包含⌈n2⌉个节点的简单路径(路径不多次访问任何节点)
2.找到至少有⌈n2⌉个节点配对的有效配对。
可以看出,在每个满足语句约束的图中,至少可以找到两个图中的一个
若找到配对,输出配对的堆数即有效的2个整数a和b,表示a和b是成对的,然后输出路径中结点数即他们在路径上出现的顺序,并且注意任何结点不能出现一次以上。

猜你喜欢

转载自blog.csdn.net/weixin_46434074/article/details/107903440
今日推荐