Educational Codeforces Round 71 (Rated for Div. 2)

B - Square Filling

题意:给出一个01矩阵,每次刷新可以将矩阵B [i,j][i+1,j][i,j+1][i+1,j+1]的一个2×2的矩阵刷为1,问需要多少次操作(不要求找出最小操作)
题解:找到一个符合的就将0刷为1,最后比较两个矩阵是否相等,相等即可以刷出,否则输出-1.

#include <cstdio>
const int N = 60 ; 
int maze[N][N] , a[N][N] ; 
int ans[N*N][2] ; 
int main(){
	int n , m ; 
	scanf ("%d%d",&n,&m) ;
	for (int i = 1 ; i <= n ; ++ i)
		for (int j = 1 ; j <= m ; ++ j)
			scanf ("%d",&maze[i][j]) ;
	int cnt = 0 ; 
	for (int i = 1 ; i < n ; ++ i){
		for (int j = 1 ; j < m ; ++ j){
			if (maze[i][j] && maze[i+1][j] && maze[i][j+1] && maze[i+1][j+1]){
				ans[cnt][0] = i , ans[cnt++][1] = j ; 
				a[i][j] = 1 , a[i+1][j] = 1 , a[i][j+1] = 1 , a[i+1][j+1] = 1 ; 
			}
		}
	}
	for (int i = 1 ; i <= n ; ++ i)
		for (int j = 1 ; j <= m ; ++ j){
			if (maze[i][j] != a[i][j]){
				printf ("-1\n") ; 
				return 0 ; 
			}
		}
	printf ("%d\n",cnt) ;
	for (int i = 0 ; i < cnt ; ++ i)
		printf ("%d %d\n",ans[i][0],ans[i][1]) ;
	return 0 ;
}
CC - Gas Pipeline

题意:给出一串01字符串要求为1的地方铺的管子两米高,0的可铺1或0 ,外面一圈每单位耗费a元,高没单位耗费b元,求最小花费。
题解:用dp当为1时加上1的花费,并且dp[i][0]要设置为无穷表示不可选,还有要注意的是两端的高度为1

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std ;
typedef long long ll ;
const int N = 2e5 + 5 ;
const ll INF = 1e15 ; 
ll dp[N][2] ;  
int main(){
	int t ; 
	cin >> t ; 
	while(t --){
		ll n , a , b ; 
		cin >>  n >> a >> b ; 
		string s ; 
		cin >> s ;
		memset(dp,0,sizeof(dp)) ;
		dp[0][0] = b , dp[0][1] = INF ; 
		ll cost = 0 ; 
		for (ll i = 1 ; i <= n ; ++ i){
			if (s[i-1] == '0'){
				dp[i][0] = min(dp[i-1][0]+a+b , dp[i-1][1]+b+2*a) ;
				dp[i][1] = min(dp[i-1][0]+2*b+2*a , dp[i-1][1]+2*b+a) ;
			}
			else
				dp[i][1] = dp[i-1][1] + 2*b + a , dp[i][0] = INF ; 
		}
		cout << dp[n][0] << endl ; 
	}
	return 0 ; 
} 
D - Number Of Permutations(容斥)

题意:求给出的二元序对x和y都不递减的排列数量。
还是看看大佬解说叭:→题解1 题解2
容斥:答案为总的排列数-(ai单调不减或者bi单调不减的排列数)+(ai,bi都单调不减的排列数)。

#include <cstdio>
#include <algorithm>
using namespace std ; 
typedef long long ll ;
const int N = 3e5 + 100 ;
const ll MOD = 998244353 ;  
ll fac[N] ; 
struct node{
	ll l , r ; 
};
node num[N] ;
void init(int n){	//计算阶乘(总方案数) 
	fac[0] = 1 ; 
	for (int i = 1 ; i <= n ; ++ i)
		fac[i] = fac[i-1]*i%MOD ; 
}
bool cmp1(node a , node b){
	return a.r < b.r ;
} 
bool cmp2(node a , node b){
	if (a.l == b.l)		return a.r < b.r ; 
	return a.l < b.l ; 
}
int main(){
	int n ; 
	scanf ("%d",&n) ;
	init(n) ;  
	for (int i = 1 ; i <= n ; ++ i)
		scanf ("%lld%lld",&num[i].l,&num[i].r) ;
	ll sum  = fac[n] , res = 1 ; 
	sort(num+1,num+1+n,cmp2) ;	//以l为第一为关键字升序排列 
	for (int i = 1 ; i <= n ; ++ i){
		int j = i ; 
		//统计l不降的个数 
		while(j+1 <= n && num[j+1].l==num[j].l)	 ++ j ; 
		res = res*fac[j-i+1]%MOD ; 
		i = j ; 
	} 
	sum = (sum-res+MOD)%MOD ; //为了防止sum变成负数先加上mod再取余
	sort(num+1,num+1+n,cmp1) ; //以r为关键字进行排序 
	res = 1 ;  
	for (int i = 1 ; i <= n ; ++ i){
		int j = i ; 
		//统计r不降的个数 
		while(j+1 <= n && num[j+1].r == num[j].r)		++ j ; 
		res = res*fac[j-i+1]%MOD ; 
		i = j ; 
	} 
	sum = (sum-res+MOD)%MOD ; 
	sort(num+1,num+1+n,cmp2) ;
	bool flag = true ; 
	for (int i = 2 ; i <= n ; ++ i){
		if (num[i].r < num[i-1].r){
			flag = false ; 
			break ; 
		}
	}
	res = 1 ; 
	if (flag){
		for (int i = 1 ; i <= n ; ++ i){
			int j = i ; 
			//统计l和r同时不降的个数 
			while(j+1 <= n && num[j+1].l==num[j].l && num[j+1].r==num[j].r)	
				++ j ; 
			res = res*fac[j-i+1]%MOD ; 
			i = j ; 
		}
		sum = (sum+res)%MOD ; 
	}
	printf ("%lld\n",sum) ;
	return 0 ; 
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值