2021.8.22 校测

期望得分 : \(100 + 60 + 20 = 180\)
实际得分 : \(10 + 60 + 0 = 70\)

【T1 套路 】

我吐了,就差一个地方 ,硬是调一个小时没看出来。

description :

给定一个一张 \(n\) 条边的有向图,现在让你将边重定向,计算其没有环方案数,并对 \(10^9 + 7\) 取模 。

$Notice : $ 每一个点只有 \(1\) 个出度。

Solution :

我们发现在原本的图中,如果有环,那么我们任意调换这个环中的边其实都可以形成正确的方案。

有一个值得注意的地方就是 : 每一个点只有一个出度

那么这句话就代表了,这张图只会是一个个的强连通分量,也就是环。

那么我们任意翻转 : 一个环有 \(n\) 个点,就有 \(n\) 条边,既然有 \(n\) 条边,那么也就对应着 \(2 ^n\) 的可能。直接算就行。

不过值得注意的就是 : 这一个环,有两种情况需要减去:

  1. 全部都翻转过来 (它还是个环,我就忘记了,导致一直输出 \(21\) , 怎么也调不出来)
  2. 全部都不翻转(没意义)

Code , 正解不正解已经没有意义了,就差一个地方

//
/*
Author : Zmonarch
Knowledge : Tarjan + 组合数学 
*/
#include <bits/stdc++.h>
#define qwq register 
#define qaq inline 
#define int long long 
#define inf 2147483647 
using namespace std ; 
const int kmaxn = 1e6 + 10 ; 
const int mod = 1e9 + 7 ; 
qaq int read() {
	int x = 0 , f = 1 ; char ch = getchar() ; 
	while(!isdigit(ch)) {if(ch == '-') f = - 1 ; ch = getchar() ;}
	while( isdigit(ch)) {x = x * 10 + ch - '0' ; ch = getchar() ;}
	return x * f ; 
}
int tot , n , m , cnt , Dfn , top , Ans = 1 ; 
struct node {
	int nxt , u , v ; 
}e[kmaxn << 1] ;
int h[kmaxn] , siz[kmaxn] , in[kmaxn] ;
int low[kmaxn] , dfn[kmaxn] , sta[kmaxn] ; 
qaq void add(int u , int v) {
	e[++tot].nxt = h[u] ; 
	e[tot].u = u ; e[tot].v = v ; 
	h[u] = tot ; 
}
qaq void Tarjan(int u) {
	dfn[u] = low[u] = ++ Dfn ; sta[++top] = u ; 
	for(qwq int i = h[u] ; i ; i = e[i].nxt) 
	{
		int v = e[i].v ; 
		if(!dfn[v]) Tarjan(v) , low[u] = min(low[u] , low[v]) ; 
		else if(!in[v]) low[u] = min(low[u] , dfn[v]) ; 
	}
	if(low[u] == dfn[u]) 
	{
		in[u] = ++ cnt ; siz[cnt]++ ; 
		while(sta[top] != u) 
		{
			in[sta[top--]] = cnt ; 
			siz[cnt]++ ; 
		}
	}
}
qaq int Qpow(int a , int b) {
	int ret = 1;  
	while(b) 
	{
		if(b & 1) ret = ret * a % mod ; 
		a = a * a % mod ; b >>= 1 ;
	}
	return ret ; 
}
signed main() {
	//freopen("road.in" , "r" , stdin) ; 
	//freopen("road.out" , "w" , stdout) ; 
	n = read() ; 
	for(qwq int i = 1 ; i <= n ; i++) 
	{
		int x = read() ; 
		add(i , x) ;
	}
	for(qwq int i = 1 ; i <= n ; i++) 
	 if(!dfn[i]) Tarjan(i) ;  
	for(qwq int i = 1 ; i <= cnt ; i++)
	{
		if(siz[i] == 1) Ans = Ans * 2 % mod ;  // 这里需要特判一下。
		else Ans = Ans * (Qpow(2 , siz[i]) - 2) % mod ;
	} 
	printf("%lld\n" , Ans) ; 
	return 0 ; 
}

【T2exLCS】

这题数据是真的水。
我考场看错题目,写的一个匹配前缀和我写的朴素暴力一个分数。都是 \(60\) , 我吐了。

Description :

求解两个串 \(s_1 , s_2\) 的最长公共子序列,子序列可不连续 。

\(l_{s_1} \leq 10^3 , l_{s_2} \leq 10^6\)

Solution :

模板题,但是我只想着 \(n^2\)

Code :

//
/*
Author : Zmonarch
Knowledge :
*/
#include <bits/stdc++.h>
#define qwq register
#define qaq inline
#define int long long
#define inf 2147483647
using namespace std ;
const int kmaxn = 1e6 + 10 ;
const int N = 1e3 + 10 ; 
qaq int read() {
	int x = 0 , f = 1 ; char ch = getchar() ;
	while(!isdigit(ch)) {if(ch == '-') f = - 1 ; ch = getchar() ;}
	while( isdigit(ch)) {x = x * 10 + ch - '0' ; ch = getchar() ;}
	return x * f ;
}
int len1 , len2; 
char s1[kmaxn] , s2[kmaxn] ; 
int f[N][N] , nxt[kmaxn][26] ; 
signed main(){
	cin >> s1 >> s2 ; len1 = strlen(s1) , len2 = strlen(s2) ; 
	for(qwq int i = 0 ; i <= len1 ; i++) 
	 for(qwq int j = 0 ; j <= len1 ; j++) 
	  f[i][j] = inf ; 
	for(qwq int i = 0 ; i <= 25; i++) 
	 nxt[len2][i] = inf ; 
	for(qwq int i = len2 - 1; i >= 0; i--)
	{
		memcpy(nxt[i] , nxt[i + 1] , sizeof(nxt[i])) ; 
		nxt[i][s2[i] - 'a'] = i ; 	
	}
	f[0][1] = nxt[0][s1[0] - 'a'] ; 
	for(qwq int i = 0 ; i <= len1 ; i++) f[i][0] = - 1; 
	for(qwq int i = 0 ; i < len1 - 1 ; i++) 
	 for(qwq int j = 0 ; j <= len1 && f[i][j] < inf ; j++) 
	  {
	  	f[i + 1][j] = min(f[i + 1][j] , f[i][j]) ; 
	  	if(j < len1) f[i + 1][j + 1] = min(f[i + 1][j + 1] , nxt[f[i][j] + 1][s1[i + 1] - 'a']) ; 
	  }
	for(qwq int i = len1 ; i ; i--) 
	 if(f[len1 - 1][i] < inf) return printf("%lld\n" , i) , 0 ; 
	return 0 ; 
}

【T3 魔方】

我竟然顺时针逆时针都没分清楚 ,写的 \(20\) 分暴力,每一个面的三种情况调换一下就有 \(20\) 了, 我吐了。

Description : 见题面

Subtask 1 : n = 1

直接模拟即可。我有点无语 。

因为有两面是相对的,所以我们只要模拟 \(3\) 个面就好了。

if(n == 1)
	{
		if((c[1] == c[2] && c[2] == c[3] && c[3] == c[4])) // 顶  
		{
			if(c[5] == c[15] && c[6] == c[16]) printf("3\n") ; 
			else if(c[9] == c[15] && c[10] == c[16]) printf("2\n") ; 
			else printf("1\n") ; 
		}
		else if((c[9] == c[10] && c[10] == c[11] && c[11] == c[12])) // 左 
		{
			if(c[1] == c[6] && c[3] == c[7]) printf("6\n") ; 
			else if(c[1] == c[20] && c[2] == c[18])  printf("5\n") ; 
			else printf("4\n") ; 
		}
		else if(c[5] == c[6] && c[6] == c[7] && c[7] == c[8]) // 前 
		{
			if(c[3] == c[14] && c[4] == c[16]) printf("9\n") ; 
			else if(c[3] == c[18] && c[4] == c[20]) printf("8\n") ; 
			else printf("7\n") ; 
		}
	}

Subtask 2 : 100 opts

暴力模拟, \(dfs\) 搜索方案 。

//
/*
Author : Zmonarch
Knowledge :
*/
#include <bits/stdc++.h>
#define qwq register
#define qaq inline
#define int long long
#define inf 2147483647
using namespace std ;
const int kmaxn = 1e6 + 10 ;
qaq int read() {
	int x = 0 , f = 1 ; char ch = getchar() ;
	while(!isdigit(ch)) {if(ch == '-') f = - 1 ; ch = getchar() ;}
	while( isdigit(ch)) {x = x * 10 + ch - '0' ; ch = getchar() ;}
	return x * f ;
}
bool flag ; 
int n ; 
int work[25] , opt[kmaxn] ; 
qaq void Solve() {
if((work[1] == work[2] && work[2] == work[3] && work[3] == work[4])) // 顶  
	{
		if(work[5] == work[15] && work[6] == work[16]) printf("3\n") ; 
		else if(work[9] == work[15] && work[10] == work[16]) printf("2\n") ; 
		else printf("1\n") ; 
	}
	else if((work[9] == work[10] && work[10] == work[11] && work[11] == work[12])) // 左 
	{
		if(work[1] == work[6] && work[3] == work[7]) printf("6\n") ; 
		else if(work[1] == work[20] && work[2] == work[18])  printf("5\n") ; 
		else printf("4\n") ; 
	}
	else if(work[5] == work[6] && work[6] == work[7] && work[7] == work[8]) // 前 
	{
		if(work[3] == work[14] && work[4] == work[16]) printf("9\n") ; 
		else if(work[3] == work[18] && work[4] == work[20]) printf("8\n") ; 
		else printf("7\n") ; 
	}
}
qaq void Modify(int id) {
	if(id == 1) 
	{
		int a = work[5] , b = work[6] , c = work[1] ; 
		work[5] = work[13] ; work[6] = work[14] ; 
		work[13] = work[24] ; work[14] = work[23] ;
		work[23] = work[10] ; work[24] = work[9] ; 
		work[9] = a ; work[10] = b ; work[1] = work[3] ; 
		work[3] = work[4] ; work[4] = work[2] ;  work[2] = c ;
	}
	else if(id == 2) 
	{
		swap(work[5] , work[24]) ; swap(work[6] , work[23]) ; 
		swap(work[13] , work[9]) ; swap(work[14] , work[10]) ; 
		swap(work[1] , work[4]) ; swap(work[2] , work[3]) ;
	}
	else if(id == 3) 
	{
		int a = work[5] , b = work[6] , c = work[1] ; 
		work[5] = work[9] ; work[6] = work[10] ;
		work[9] = work[24] ; work[10] = work[23] ; 
		work[23] = work[14] ; work[24] = work[13] ; 
		work[13] = a ; work[14] = b ; work[1] = work[2] ; 
		work[2] = work[4] ; work[4] = work[3] ; work[3] = c ; 
	}
	else if(id == 4) 
	{
		int a = work[1] , b = work[3] , c = work[9] ; 
		work[1] = work[21] ; work[3] = work[23] ; 
		work[21] = work[17] ; work[23] = work[19] ; 
		work[17] = work[5] ; work[19] = work[7] ; 
		work[5] = a ; work[7] = b ; work[9] = work[11] ; 
		work[11] = work[12] ; work[12] = work[10] ; work[10] = c ; 
	}
	else if(id == 5) 
	{
		swap(work[1] , work[17]) ; swap(work[3] , work[19]) ; 
		swap(work[5] , work[21]) ; swap(work[7] , work[23]) ; 
		swap(work[9] , work[12]) ; swap(work[10] , work[11]) ; 
	}
	else if(id == 6) 
	{
		int a = work[1] , b = work[3] , c = work[9] ; 
		work[1] = work[5] ; work[3] = work[7] ; 
		work[5] = work[17] ; work[7] = work[19] ; 
		work[17] = work[21] ; work[19] = work[23]; 
		work[21] = a ; work[23] = b ; 
		work[9] = work[10] ; work[10] = work[12] ; work[12] = work[11] ; work[11] = c ; 
	}
	else if(id == 7) 
	{
		int a = work[3] , b = work[4] , c = work[5] ; 
		work[3] = work[12] ; work[4] = work[10] ; 
		work[10] = work[17] ; work[12] = work[18] ; 
		work[17] = work[15] ; work[18] = work[13] ; 
		work[13] = a ; work[15] = b ; 
		work[5] = work[7] ; work[7] = work[8] ; work[8] = work[6] ; work[6] = c ; 
	}
	else if(id == 8) 
	{
		swap(work[3] , work[18]) ; swap(work[4] , work[17]) ; 
		swap(work[13] , work[12]) ; swap(work[15] , work[10]) ; 
		swap(work[5] , work[8]) ; swap(work[6] , work[7]) ; 
	}
	else if(id == 9) 
	{
		int a = work[3] , b = work[4] , c = work[5] ; 
		work[3] = work[13] ; work[4] = work[15] ; 
		work[13] = work[18] ; work[15] = work[17] ; 
		work[17] = work[10] ; work[18] = work[12] ; 
		work[12] = a ; work[10] = b ; 
		work[5] = work[6] ; work[6] = work[8] ; work[8] = work[7] ; work[7] = c ;  
	}
}
qaq void Dfs(int x , int lst) {
	bool tag = 0 ; 
	for(qwq int i = 0 ; i < 6 ; i++) 
	{
		int tmp = work[(i * 4) + 1] ; 
		for(qwq int j = 1 ; j <= 4 ; j++) 
		 if(work[(i * 4) + j] != tmp)
		 {	
		 	tag = 1 ; break;
		 }
		if(tag) break ; 
	}
	if(!tag) 
	{
		flag = 1 ; x-- ; 
		for(qwq int i = 1 ; i < x ; i++) printf("%lld " , opt[i]) ; 
		printf("%lld\n" , opt[x]) ; 	
		return ; 
	}
	if(x == n + 1) return ; 
	int a[25] ; 
	for(qwq int i = 0 ; i < 6 ; i++) 
	 for(qwq int j = 1 ; j <= 4 ; j++) 
	  a[(i * 4) + j] = work[(i * 4) + j] ; 
	for(qwq int i = 0 ; i <= 2 ; i++) 
	{
		if(lst == i) continue ; 
		for(qwq int j = (i * 3 + 1) ; j <= (i * 3 + 3) ; j++) 
		{
			if(flag) return ;
			Modify(j) ; opt[x] = j ; 
			Dfs(x + 1 , i) ; 
			if(flag) return ; 
			for(qwq int k = 0 ; k < 6 ; k++) 
			 for(qwq int z = 1 ; z <= 4 ; z++) 
			  work[(k * 4) + z] = a[(k * 4) + z] ; 
		}
	}		
}
signed main() {
//	freopen("cube.in" , "r" , stdin) ; 
//	freopen("cube.out" , "w" , stdout) ; 
	n = read() ; 
	for(qwq int i = 0 ; i < 6 ; i++) 
	 for(qwq int x , j = 1 ; j <= 4 ; j++) 
	  work[(i * 4) + j] = read() ; 
	if(n == 1) Solve() ; 
	else Dfs(1 , - 1) ; 
	return 0 ;
}
posted @ 2021-08-22 17:22  SkyFairy  阅读(54)  评论(5编辑  收藏  举报