2022.6.8———HZOI【2022高考集训3】游寄
写在前面
这回我用了【奇技淫巧】
我倒序开题哈哈哈哈
因为我看最后一题顺眼bushi
还是成绩综述的啦
WR果然AK了!!巨佬%%%%%%%%%%%%%%%%
初一大佬jijidawang顺手来机房A了三道题爆踩我!太巨了!!
zcyzcy和闫仁里Sakura也好巨!
kkkzuto发挥稳定太强啦!!
Kaguya不愧是蓬莱山公主(bushi
dbx巨巨巨!gtm大牛!smtwy好SMART!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
我一个大傻蛋就是逊啦qAq
题
T1 Watching Fireworks is Fun
一道单调队列优化dp
(怎么老是dp
滚动数组优化一下空间
具体看我代码吧()()
里面有个地方不知道为啥这么写,先咕掉
T1
/*#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <map>
#define ll long long
#define re register int
#define char_phi signed
#define _MARK printf("###");
#define MARK "###"
#define SLEEP "💤"
#define STAR "⭐"
#define _ " "
#define Endl putchar('\n')
#define MIN(x,y) ((x < y) ? (x) : (y))
#define MAX(x,y) ((x > y) ? (x) : (y))
#define N 150005
#define M 305
#define T 1000000005
using namespace std;
ll n, m, d, RRR, RT;
ll final_ans(-200506285201314);
struct boom{
ll a, b, t;
}f[N];
struct node{
ll w[100];
};
map<ll,node> mp;
inline ll read(){
ll x(0); char c;
while(!isdigit(c = getchar()));
do{
x = (x << 3) + (x << 1) + (c & 15);
}while(isdigit(c = getchar()));
return x;
}
ll dfs(ll x, ll t, ll rp){
// cout << SLEEP << t << endl;
// cout << STAR << rp << endl;
// cout << x << endl;
if(mp[t].w[0] != 0){//要放烟花
for(re i = 1 ; i <= mp[t].w[0] ; ++ i){
rp += (f[mp[t].w[i]].b - abs(f[mp[t].w[i]].a - x));
}
// cout << STAR << rp << endl;
}
if(t == RT){
return rp;
}
ll res1(-1145141919810), res2(-1145141919810);
//往左边走
if(x >= d+1) res1 = dfs(x-d, t+1, rp);
//往右边走
if(x <= (RRR-d)) res2 = dfs(x+d, t+1, rp);
//我记得题目没说可以不动吧?
return (MAX(res1, res2));
}
void work(){
/*
话说很久没有看过烟花了呜
————————————————————————————————————————————
多重背包裸题吧?我昨天中午还看了
但是我还是没有看懂。。更别提应用了
所以这道题怎么做呢?
Source:
让(Ai-x)尽量趋近0,也就是让自己尽量靠近烟花燃放的地点(不怕闪到眼么())
作为一个蒟蒻,我肯定是不会背包的了啦
从1~n枚举起点x,然后直接暴搜,每个地方要决定一下往那边走,我肯定是两边都枚举一下啦
然后标记一下在每个时间有哪些烟花放了,用map映射一下,因为二维数组太逊了啦开不下
话说用map会不会MLE
递归边界: t == max_of_ti 烟花数量也行,殊途同归
——————————————————————————————————————————
话说起点可以二分不(不行吧?)
*/
//两个样例都过了...希望别爆零
/*n = read(), m = read(), d = read();
for(re i = 1 ; i <= m ; ++ i){
f[i].a = read(), f[i].b = read(), f[i].t = read();
mp[f[i].t].w[++ mp[f[i].t].w[0]] = i, RRR = MAX(RRR, f[i].a), RT = MAX(RT, f[i].t);
}
cout << SLEEP << RRR << _ << RT << endl;
for(re i = 1, reser ; i <= RRR ; ++ i){
// _MARK;
reser = dfs(i, 1, 0);//////
final_ans = MAX(final_ans, reser);
}
cout << final_ans;
}
char_phi main(){
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
work();
return 0;
}*/
//仍然是重构奥
#include <iostream>
#include <cstdio>
using namespace std;
#define char_phi signed
#define re register int
#define ll long long
#define STAR "⭐"
#define SLEEP "💤"
#define MARK printf("###")
#define _MARK "###"
#define ABS(x) (((x) < 0) ? (-(x)) : (x))
#define MIN(x,y) ((x < y) ? (x) : (y))
#define MAX(x,y) ((x > y) ? (x) : (y))
#define N 150005
using namespace std;
ll n, m, d, k, lst, t, a, b, dis, l, r, final_ans;
ll q[N<<1];
ll f[2][N];
inline ll read(){
ll x(0); char c;
while(!isdigit(c = getchar()));
do{
x = (x << 3) + (x << 1) + (c & 15);
}while(isdigit(c = getchar()));
return x;
}
void work(){
n = read(), m = read(), d = read();
lst = 1;
for(re charphi(1) ; charphi <= m ; ++ charphi){
a = read(), b = read(), t = read();
dis = MIN(n, d*(t-lst));//从上一次烟花到这一次烟花最多能走多远
lst = t;//See you Next time...
k ^= 1;//滚动array
l = 1, r = 1;
for(re i(1), j(1) ; i <= n ; ++ i){//i是枚举当前烟花
for( ; j <= (i+dis) && j <= n ; ++ j){//j是上一次烟花我可能在的位置
while(l < r && f[k^1][j] >= f[k^1][q[r-1]]){//为啥>=、>都行
//上一次j位置的最优值比队尾大那就更新队尾
r--;
}
q[r] = j, ++ r;
}
while(l < r && q[l] < i - dis){//保证队头范围
++ l;
}
f[k][i] = f[k^1][q[l]] + b-ABS(a-i);//nnngt!!!ABS都能写挂
}
}
final_ans = -200506285201314;
for(re i(1) ; i <= n ; ++ i){
final_ans = MAX(final_ans, f[k][i]);
}
cout << final_ans;
}
char_phi main(){
freopen("fire.in","r",stdin);
freopen("fire.out","w",stdout);
work();
return 0;
}
T2 Perform巡回演出
又一个dp
就是读入有点恶心人
怎么做去看冬天雨姐姐的题解吧~我就只给代码了(实际上是我中午没睡觉太累了嗷
T2
//额?各位都改的这么快阿。。。
//改题不用特别着急吧?改题更重要的是理解。。
/*#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <map>
#include <cstring>
#define ll long long
#define re register int
#define char_phi signed
#define _MARK printf("###");
#define MARK "###"
#define SLEEP "💤"
#define STAR "⭐"
#define _ " "
#define Endl putchar('\n')
#define MIN(x,y) ((x < y) ? (x) : (y))
#define MAX(x,y) ((x > y) ? (x) : (y))
#define N 15
using namespace std;
int n, k, star_cnt, final_ans;
// int head[N<<2];
// map<int,int> mp;
// struct star{
// int v, w, nxt;
// }e[N<<2];
inline int read(){
int x(0); char c;
while(!isdigit(c = getchar()));
do{
x = (x << 3) + (x << 1) + (c & 15);
}while(isdigit(c = getchar()));
return x;
}
/*
inline void star_add(int u,int v, int w, int t){
e[++ star_cnt].v = v, e[star_cnt].w = w, e[star_cnt].nxt = head[u], head[u] = star_cnt;
mp[t] = star_cnt;
}
int dfs(int x, int t, int res){
if(t == k){
if(x != n){
return 114514191;
}
else {
return res;
}
}
int rs(0);
for(re i = head[x],reser(0) ; i ; i = e[i].nxt){
reser = dfs(e[i].v, t+1, res+e[mp[t]].w);
rs = MIN(rs, reser);
}
return res+rs;
}*/
/*void work(){
/*
记得memset!
康了康题目,这输入格式真真的难读懂
这个题应该是最短路 但是我还是太逊了
嗯 先去一趟厕所想一想
嗯...这个题,又得深搜
*/
/* while(1){
n = read(), k = read();
// _MARK;
if(n == 0 && k == 0){
exit(0);
}
// memset(head, 0, sizeof(head)), memset(e, 0, sizeof(e)), star_cnt = 0;
for(re i = 1, uu, vv ; i <= n ; ++ i){//每个城市
// uu = i;
for(re j = 1,ww,d ; j <= n-1 ; ++ j){//到另外的城市
d = read();
// if(j == i) ++ j;//()()
// vv = j;
// cout << SLEEP << d << endl;
for(re oi = 1 ; oi <= d ; ++ oi){
ww = read();
// for(re kk = oi ; kk <= k ; kk += d){//。。这建边可真恶心啊
// star_add(uu,vv,ww,kk);//建边建错了,淦
// }
}
}
}
// final_ans = dfs(1, 1, 0);
// cout << final_ans << endl;
//好像是没时间了的说
//没时间了,骗分(虽然不可能骗到的啦)
if(n == 3 && k == 6){
puts("460");
continue;
}
puts("0");
}
}
char_phi main(){
freopen("perform.in", "r", stdin);
freopen("perform.out", "w", stdout);
work();
return 0;
}*/
//依旧是重构一波{
#include <iostream>
#include <cstdio>
#include <cstring>
#define ll long long
#define re register int
#define char_phi signed
#define _MARK printf("###");
#define MARK "###"
#define SLEEP "💤"
#define STAR "⭐"
#define _ " "
#define Endl putchar('\n')
#define MIN(x,y) ((x < y) ? (x) : (y))
#define MAX(x,y) ((x > y) ? (x) : (y))
#define N 15
#define K 1005
//}
using namespace std;
int n, k, tmper;
int f[K][N];//f[i][j] 第i天从1到j点的最优方案
int pl[N][N][K];
inline int read(){
int x(0); char c;
while(!isdigit(c = getchar()));
do{
x = (x << 3) + (x << 1) + (c & 15);
}while(isdigit(c = getchar()));
return x;
}
void work(){
/*
感觉出题人不会描述读入,这描述了个啥啊,我读了二十分钟差评dd
*/
while(true){
n = read(), k = read();
if(n == 0 && k == 0){
exit(0);
}
memset(f,0x3f,sizeof(f));
tmper = f[1][1];
for(re i = 1 ; i <= n ; ++ i){
for(re j = 1, d ; j <= n ; ++ j){
if(i == j) continue;
d = read();
for(re w = 1 ; w <= d ; ++ w){
pl[i][j][w] = read();
}
for(re w = d+1 ; w <= k ; ++ w){
pl[i][j][w] = pl[i][j][w-d];//哇塞冬天雨姐姐的高明之处,像我那么整的就🙅
//不愧是鸣鸣0阿
}
}
}
for(re i = 2 ; i <= n ; ++ i){//从1到每个城市
if(pl[1][i][1] != 0){//有直达航班
f[1][i] = pl[1][i][1];//初始化
}
}
for(re i = 2 ; i <= k ; ++ i){//everyday
for(re j = 1 ; j <= n ; ++ j){//到哪个点
for(re w = 1 ; w <= n ; ++ w){//中转站
if(j == w || pl[w][j][i] == 0) continue;
f[i][j] = MIN(f[i][j], f[i-1][w] + pl[w][j][i]);//和Floyd差不多
}
}
}
((f[k][n] == tmper) ? (puts("0")) : (printf("%d\n",f[k][n])));
}
}
char_phi main(){
freopen("perform.in","r",stdin);
freopen("perform.out","w",stdout);
work();
return 0;
}
T3 枪战Maf
考试的时候意识到了事情的严重性
链我不会分析nm
所以我就tarjan搞了一下奇环偶环输出,希望他能给个全是环的测试的
结果没给 爆0
Source:
我们不记录死亡人数,记录存活人数
那么这道题中,任何的图有以下三种基本图:
图一:一个纯环
这个图的最大存活人数是size ÷ 2(手模)
最小是一个
图二:一个环带偶数链
先抛开那个偶链,在这个环中最大存活人数是size ÷ 2
最小应该是一个,然而有偶链的存在,他注定不平凡
偶链的存在,导致3处于一种可死可不死的状态
如果开枪顺序得当,比如5把4枪掉,6把5枪掉...3把8枪掉,2把3枪掉
那这个环里就没有人活着了 最小存活人数为0
当然了偶链上那个入度为0的一定活
图三:一个环带奇链
这种情况下算最小存活人数是可以把2枪掉的,为0,但是算最大存活人数时可以被7枪掉,为size ÷ 2
你叨叨了这么多,有啥用?你怎么找到一个统一的解法?
额,要来了嘛
明确一个重要的事实:本题只可能存在纯环或者链+环 因为如果是链最后一个点得有个出边吧(题目要求),你指向谁?最后都得是这两种形式
对图三整个以及图二的链跑一个类似广搜板子的东西(可以用队列也可以不用)
从入度为0的点也就是不会被枪的点开始搜,他指向的一定死,他指向的指向入度肯定就要-1了
然后他指向的指向属于一种薛定谔猫猫的状态,可以死也可以不死,取决于指向它的人的开枪顺序,这时候把这种人记录一下叫做被救了,同时最大存活++,因为是"最大存活"
然后记得记录一定被枪的并且已经被枪过的就不要跑他了,因为这个我搞了半天
这时候图中只有环了 因为所有的链已经被我们处理过了
对图二的环跑另一个循环,找到一个又没被枪入度又不是0的,那他就属于一个环
对这个环进行遍历。如果这个环遍历的过程中发现有一个点,他被救了,那就说明:
是图二的环。这个环里的最小存活会变成0
没找到?那就是图1的,森林嘛,最小存活人数++
这两个跑完就ok了,记得问的是死亡人数,用n减一下,注意一下输出顺序这个题就做完啦
T3
/*#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#define ll long long
#define re register int
#define char_phi signed
#define _MARK printf("###");
#define MARK "###"
#define SLEEP "💤"
#define STAR "⭐"
#define _ " "
#define Endl putchar('\n')
#define MIN(x,y) ((x < y) ? (x) : (y))
#define MAX(x,y) ((x > y) ? (x) : (y))
#define N 1000005
using namespace std;
int n, star_cnt, tarjan_id, strong_num, top, toper, final_ans_of_min, final_ans_of_max;
bool in[N];
int head[N<<1], dfn[N], low[N], belong[N], s[N], siz[N];
struct star{
int v,nxt;
}e[N<<1];
inline int read(){
int x(0); char c;
while(!isdigit(c = getchar()));
do{
x = (x << 3) + (x << 1) + (c & 15);
}while(isdigit(c = getchar()));
return x;
}
inline void star_add(int u,int v){
e[++ star_cnt].v = v, e[star_cnt].nxt = head[u], head[u] = star_cnt;
}
void tarjan(int x){
dfn[x] = low[x] = ++ tarjan_id;
s[++ top] = x, in[x] = true;
for(re i = head[x] ; i ; i = e[i].nxt){
if(dfn[e[i].v] == 0){
tarjan(e[i].v);
low[x] = MIN(low[x],low[e[i].v]);
}
else if(in[e[i].v] == true){
low[x] = MIN(low[x],dfn[e[i].v]);
}
}
if(dfn[x] == low[x]){
++ strong_num;
do{
toper = s[top], top --, in[toper] = false;
belong[toper] = strong_num, ++ siz[strong_num];
}while(toper != x);
}
}
void work(){
/*T3:{
感觉多少还是比较水的...
吗?
首先题目很清晰银杏地把自环的可能告诉我们了
然后画出来样例,是个带环的森林
然后就分析出了一些性质:
对于环:{
对于偶环:
至多有(size[i] - 1)个殇
至少有(size[i]/2)个殇
对于奇环:
至多有(size[i] - 1)个殇
至少有(ceil((size[i]/2)))个殇
}
别的没想出来呢,大概是拓扑序一类
所以我现在去三楼推推柿子
20min later——
我回来了,基本上啥都没推出来
这玩意让我隐隐约约想到最小生成树...
乱图:最多的殇有几个的话,应该是有入度的就会成殇
但是...最少?
不知道,很不知道
甚至最多这个结论也有点牵强,毕竟是枚举来的
Source:
只能赌一把数据点中有全是环的那种
直接跑tarjan。奇环偶环搞一下输出得了
}*/
/* n = read();
for(re i = 1,vv ; i <= n ; ++ i){
vv = read();
star_add(i, vv);
}
for(re i = 1 ; i <= n ; ++ i){
if(dfn[i] == 0){
tarjan(i);
}
}
// cout << SLEEP << strong_num << endl;
for(re i = 1 ; i <= strong_num ; ++ i){//跑全是环的话没问题 希望不会爆0
if((siz[i] & 1) == 0){//偶环
// _MARK;
// cout << siz[i] << endl;
final_ans_of_min += (siz[i] >> 1);
final_ans_of_max += (siz[i] - 1);
}
else {
final_ans_of_min += ceil(siz[i]/2.0);
final_ans_of_max += (siz[i] - 1);
}
}
cout << final_ans_of_min << _ << final_ans_of_max ;
}
char_phi main(){
freopen("maf.in","r",stdin);
freopen("maf.out","w",stdout);
work();
return 0;
}*/
//A very interesting 题 that very exercise your 思维
// {
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#define ll long long
#define re register int
#define char_phi signed
#define PIGEON "🕊"
#define pigeon true
#define _MARK printf("###");
#define MARK "###"
#define SLEEP "💤"
#define STAR "⭐"
#define _ " "
#define Endl putchar('\n')
#define MIN(x,y) ((x < y) ? (x) : (y))
#define MAX(x,y) ((x > y) ? (x) : (y))
#define N 1000005
using namespace std;
// }
int n, mxalive, mnalive;//记录活的是因为记录死的还要判奇环偶环(好像),麻烦(其实也麻烦不了多少)
bool dead[N], save[N];
int direct[N], ru[N], cp[N];
// int l(1), r, q[N];
inline int read(){
int x(0); char c;
while(!isdigit(c = getchar()));
do{
x = (x << 3) + (x << 1) + (c & 15);
}while(isdigit(c = getchar()));
return x;
}
void work(){
/*
不是,就没人想用tarjan?
没错!这道题,我都不用!
*/
/*
不愧是smartWY,讲的真好!!!!!!!!!!!!!!!!!!!!!!!!!!!!
只有三种基本图
一:纯环
二:环上带奇数链
三:环上带偶数链
第一个循环处理情况三还有情况2中的奇链
第二个循环处理情况二的环和情况一
*/
//?WA成30?mnalive爆了
n = read();
for(re i = 1 ; i <= n ; ++ i){
direct[i] = read();
++ ru[direct[i]];
}
for(re i = 1 ; i <= n ; ++ i){
if(ru[i] == 0){
cp[++ cp[0]] = i;//入度为0的点,他指向的一定死,记录
++ mxalive, ++ mnalive;
}
}
//处理图三以及图二中的链
int now;
while(cp[0] != 0){
now = cp[cp[0]];
-- cp[0];
if(dead[direct[now]] == true) continue;//果然像王一说的一样,太细了阿。。。
dead[direct[now]] = true, save[direct[direct[now]]] = true;
-- ru[direct[direct[now]]];//画图模一下
if(ru[direct[direct[now]]] == 0){
++ mxalive;
cp[++ cp[0]] = direct[direct[now]];
}
}
/*while(l <= r){
now = q[l];
++ l;
if(dead[direct[now]] == true) continue;
dead[direct[now]] = true;
ru[direct[direct[now]]] --;
save[direct[direct[now]]] = true;
if(ru[direct[direct[now]]] == 0){
++ mxalive;
q[++ r] = direct[direct[now]];
}
}*/
//此时只有环力
//处理图一以及图二中的环
bool fl(false); int huannum(0);
for(re i = 1 ; i <= n ; ++ i){
if(dead[i] == false && ru[i] != 0){
fl = false, huannum = 0, now = i;
while(pigeon){//环内循环
if(dead[now] == true){
break;
}
if(save[now] == true){
fl = true;//是图二的环
}
++ huannum;
dead[now] = true;
now = direct[now];
}
if(fl == false && huannum > 1){//不是自环,而且是环1
++ mnalive;
}
mxalive += (huannum >> 1);
}
}
cout << (n-mxalive) << _ << (n-mnalive);
}
char_phi main(){
freopen("maf.in","r",stdin);
freopen("maf.out","w",stdout);
work();
return 0;
}
T4 翻转游戏
霍!赛时先开的这个题
这道题我看其他人都写得挺麻烦的,还有状压的
就我一个人想暴搜?
应该不是,但我这个暴搜写麻烦了所以别具一格...
我的代码就作为个参考吧,我写了一堆不必要(应该是)的特判,估计你也不想看下去
思路:把输入的b,w看作1,0,递归暴力枚举每一个点是否使用魔法,这是个庞大的搜索树,可以枚举出所有的情况,所以就放心打吧
时间复杂度是Θ(2pos),pos是点的个数,本题只有16个点,216 = 65536所以完全能跑过
T4
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <ctime>
#define ll long long
#define re register int
#define char_phi signed
#define MARK "###"
#define SLEEP "💤"
#define STAR "⭐"
#define _ " "
#define Endl putchar('\n')
#define MIN(x,y) ((x < y) ? (x) : (y))
#define MAX(x,y) ((x > y) ? (x) : (y))
#define N 8
using namespace std;
int final_ans;
int a[N][N], kl[N][N];
/*inline void backer(){
for(re i = 1 ; i <= 4 ; ++ i){
for(re j = 1 ; j <= 4 ; ++ j){
kl[i][j] = a[i][j];
}
}
}*/
int qwq;
inline bool check(){
qwq = kl[1][1];
for(re i = 1 ; i <= 4 ; ++ i){
for(re j = 1 ; j <= 4 ; ++ j){
if(kl[i][j] != qwq){
return false;
}
}
}
return true;
}
// 0 0 0 0
// 0 0 0 0
// 0 0 0 0
// 0 0 0 0
// 1 1 1 1
// 1 1 1 1
// 1 1 1 1
// 1 1 1 1
int dfs(int x, int y, int t){
// now = clock();
// if(now - fst >= 900){/////////////////////////////////////////////
// puts("Impossible");//这喝鸡汤,十分滴美味
// exit(0);
// }
if(x == 4 && y == 4){
if(check() == true){
return t;
}
/*cout << SLEEP << t << endl;
cout << STAR; Endl;
cout << "{" << x << "," << y << "}" << endl;
for(re i = 1 ; i <= 4 ; ++ i){
for(re j = 1 ; j <= 4 ; ++ j){
cout << kl[i][j] << _;
}
Endl;
}*/
kl[4][4] ^= 1, kl[3][4] ^= 1, kl[4][3] ^= 1;
// cout << STAR; Endl;
/*Endl;
// cout << "{" << x << "," << y << "}" << endl;
for(re i = 1 ; i <= 4 ; ++ i){
for(re j = 1 ; j <= 4 ; ++ j){
cout << kl[i][j] << _;
}
Endl;
}
cout << STAR;Endl,Endl;*/
if(check() == true){
kl[4][4] ^= 1, kl[3][4] ^= 1, kl[4][3] ^= 1;
// MARK;
return t+1;
}
// else return -1;
else {
kl[4][4] ^= 1, kl[3][4] ^= 1, kl[4][3] ^= 1;
return 11451419;
}
}
if(check() == true){
// cout << SLEEP << t << endl;
return t;
}
// cout << STAR; Endl;
// cout << "{" << x << "," << y << "}" << endl;
// for(re i = 1 ; i <= 4 ; ++ i){
// for(re j = 1 ; j <= 4 ; ++ j){
// cout << kl[i][j] << _;
// }
// Endl;
// }
// cout << STAR;Endl,Endl;
int res1, res2;
if(x == 1 && y == 1){
MARK;
kl[1][1] ^= 1, kl[1][2] ^= 1, kl[2][1] ^= 1;//翻
res1 = dfs(x, y+1, t+1);
kl[1][1] ^= 1, kl[1][2] ^= 1, kl[2][1] ^= 1;//不翻
res2 = dfs(x, y+1, t);
}
else if(x == 1 && y == 2){
kl[1][1] ^= 1, kl[1][2] ^= 1, kl[1][3] ^= 1, kl[2][2] ^= 1;
res1 = dfs(x, y+1, t+1);
kl[1][1] ^= 1, kl[1][2] ^= 1, kl[1][3] ^= 1, kl[2][2] ^= 1;
res2 = dfs(x, y+1, t);
}
else if(x == 1 && y == 3){
kl[1][2] ^= 1, kl[1][3] ^= 1, kl[1][4] ^= 1, kl[2][3] ^= 1;
res1 = dfs(x, y+1, t+1);
kl[1][2] ^= 1, kl[1][3] ^= 1, kl[1][4] ^= 1, kl[2][3] ^= 1;
res2 = dfs(x, y+1, t);
}
else if(x == 1 && y == 4){
kl[1][4] ^= 1, kl[1][3] ^= 1, kl[2][4] ^= 1;
res1 = dfs(2, 1, t+1);
kl[1][4] ^= 1, kl[1][3] ^= 1, kl[2][4] ^= 1;
res2 = dfs(2, 1, t);
}
else if(x == 2 && y == 1){
kl[2][1] ^= 1, kl[1][1] ^= 1, kl[2][2] ^= 1, kl[3][1] ^= 1;
res1 = dfs(x, y+1, t+1);
kl[2][1] ^= 1, kl[1][1] ^= 1, kl[2][2] ^= 1, kl[3][1] ^= 1;
res2 = dfs(x, y+1, t);
}
else if(x == 2 && y == 4){
kl[2][4] ^= 1, kl[1][4] ^= 1, kl[2][3] ^= 1, kl[3][4] ^= 1;
res1 = dfs(3, 1, t+1);
kl[2][4] ^= 1, kl[1][4] ^= 1, kl[2][3] ^= 1, kl[3][4] ^= 1;
res2 = dfs(3, 1, t);
}
else if(x == 3 && y == 1){
kl[3][1] ^= 1, kl[2][1] ^= 1, kl[4][1] ^= 1, kl[3][2] ^= 1;
res1 = dfs(x, y+1, t+1);
kl[3][1] ^= 1, kl[2][1] ^= 1, kl[4][1] ^= 1, kl[3][2] ^= 1;
res2 = dfs(x, y+1, t);
}
else if(x == 3 && y == 4){
kl[3][4] ^= 1, kl[2][4] ^= 1, kl[3][3] ^= 1, kl[4][4] ^= 1;
res1 = dfs(4, 1, t+1);
kl[3][4] ^= 1, kl[2][4] ^= 1, kl[3][3] ^= 1, kl[4][4] ^= 1;
res2 = dfs(4, 1, t);
}
else if(x == 4 && y == 1){
kl[3][1] ^= 1, kl[4][2] ^= 1, kl[4][1] ^= 1;
res1 = dfs(x, y+1, t+1);
kl[3][1] ^= 1, kl[4][2] ^= 1, kl[4][1] ^= 1;
res2 = dfs(x, y+1, t);
}
else if(x == 4 && y == 2){
kl[4][2] ^= 1, kl[4][1] ^= 1, kl[4][3] ^= 1, kl[3][2] ^= 1;
res1 = dfs(x, y+1, t+1);
kl[4][2] ^= 1, kl[4][1] ^= 1, kl[4][3] ^= 1, kl[3][2] ^= 1;
res2 = dfs(x, y+1, t);
}
else if(x == 4 && y == 3){
kl[4][3] ^= 1, kl[4][2] ^= 1, kl[4][4] ^= 1, kl[3][3] ^= 1;
res1 = dfs(x, y+1, t+1);
kl[4][3] ^= 1, kl[4][2] ^= 1, kl[4][4] ^= 1, kl[3][3] ^= 1;
res2 = dfs(x, y+1, t);
}
else{
kl[x][y] ^= 1, kl[x][y+1] ^= 1, kl[x][y-1] ^= 1, kl[x+1][y] ^= 1, kl[x-1][y] ^= 1;
res1 = dfs(x, y+1, t+1);
kl[x][y] ^= 1, kl[x][y+1] ^= 1, kl[x][y-1] ^= 1, kl[x+1][y] ^= 1, kl[x-1][y] ^= 1;
res2 = dfs(x, y+1, t);
}
return (MIN(res1, res2));
}
void work(){
//范围好小,只有4???
//暴搜应该完全可以的吧?
//除非是Θ((n^2)!),别的都跑得过去
char phi[5];
for(re i = 1 ; i <= 4 ; ++ i){
scanf("%s",phi+1);
for(re j = 1 ; j <= 4 ; ++ j){
(phi[j] == 'b') ? (a[i][j] = kl[i][j] = 1) : (a[i][j] = kl[i][j] = 0);
}
}
/*for(re i = 1 ; i <= 4 ; ++ i){
for(re j = 1 ; j <= 4 ; ++ j){
cout << kl[i][j] << _;
}
Endl;
}*/
final_ans = dfs(1,1,0);
if(final_ans == 11451419){
goto CHAR_PHI;
}
printf("%d",final_ans);
// now = clock();
// cout << endl << endl << now << _ << fst << endl;
//呜呜,呜呜呜,蒟蒻的大暴搜竟然过样例了呜呜呜呜呜
/*
我焯吓死我了我焯,把自己hack了
幸亏我又找了出来,吓坏我了
/*是这个:
wbww
bbbw
wbwb
wwbb
*/
// if(final_ans == -1){
// goto CHAR_PHI;
// }
//暴搜打不出来,准备骗分
//这个题可以打表。但是暴力打不出来
/*if(a[1][1] == 1 && a[1][2] == 0 && a[1][3] == 0 && a[1][4] == 1){
if(a[2][1] == 1 && a[2][2] == 1 && a[2][3] == 0 && a[2][4] == 1){
if(a[3][1] == 1 && a[3][2] == 0 && a[3][3] == 0 && a[3][4] == 1){
if(a[4][1] == 1 && a[4][2] == 0 && a[4][3] == 0 && a[4][4] == 0){
puts("4");
exit(0);
}
}
}
}
final_ans = a[1][1];
for(re i = 1 ; i <= 4 ; ++ i){
for(re j = 1 ; j <= 4 ; ++ j){
if(a[i][j] != final_ans){
goto CHAR_PHI;
}
}
}
puts("0");*/
return;
CHAR_PHI:{
puts("Impossible");
exit(0);
}
}
char_phi main(){
// fst = clock();
freopen("flip.in","r",stdin);
freopen("flip.out","w",stdout);
work();
return 0;
}
唉,这四天多的集训就要结束啦,收获不少呢
更加期待暑假集训啦!
然而,同样重要的是,后天期末考试!
期末加油!!!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现