517-coding #1 枚举算法
作者:互联网
枚举的技巧(什么是枚举)
暴力? 模拟? for? dfs? bfs? ...
巧妙的枚举。(优化时间复杂度、统计区间的贡献)
... 暴力大家都会 ... 优化暴力... 变成正解。
About DFS/BFS
二进制状态压缩表示。
折办搜索然后匹配累加贡献。
A* IDA* 搜索
迭代加深的DFS...
About 序列上的枚举
若答案具有单调性可考虑枚举一个端点,二分右端点,加上整一段对答案的贡献。
若答案具有单调性可考虑双指针,加上整一段对答案的贡献。
...
Some Qestions
Problem A
给你一个4*4的黑白棋盘,每次可以将一个棋子反转颜色,同时这个棋子的上下左右都会反转,
问你最少反转几次,可以将整个棋盘变成同色的
Sol :显然不同格子最多只能被翻转一次(如果翻转两次那么必然会重复)
所以最多是需要$2^{4 \times 4}$的翻转状态。
直接枚举每一种点击可能,这时候状态压缩处理即可。
#include<iostream> #include<stdio.h> #include<string.h> #include<vector> #include<algorithm> using namespace std; char board[4][4]; int tot=17; char new_b[4][4]; static int dir[5][2]={{1,0},{-1,0},{0,0},{0,1},{0,-1}}; bool check(){ for(int i=0;i<4;i++) for(int j=0;j<4;j++) if(new_b[i][j]!=new_b[0][0]) return false; return true; } int main(){ int tT; cin>>tT; while(tT--){ tot=17; for(int i=0;i<4;i++) { for(int j=0;j<4;j++) { cin>>board[i][j]; } } // for(int i=0;i<(1<<16);i++){ for(int a=0;a<4;a++) { for(int b=0;b<4;b++) { new_b[a][b]=board[a][b]; } } int t=0; for(int j=0;j<16;j++){ if(((1<<j)&i)){ t++; int x=j/4,y=j%4; for(int k=0;k<5;k++){ int xx=x+dir[k][0]; int yy=y+dir[k][1]; if(xx<0 || yy<0 || xx>=4 || yy>=4) continue; new_b[xx][yy]=new_b[xx][yy]=='w'?'b':'w'; } } } if(check()) { tot=min(tot,t); } } if(tot<17) { cout<<tot<<endl;; } else { cout<<"Impossible"<<endl;; } if(tT != 0) { puts(""); } } return 0; }A.cpp
Problem B
给你n S,以及n个数,求最短的连续子序列的长度使得这个连续子序列的和大于等于S
对于100%的数据 $1 \leq n\leq 10^5$
Problem C
给出一个数列$a_{n}$ 求有多少区间的xor之和等于区间的数的和
对于100%的数据 $1 \leq n \leq 10^5$
Sol :
标签:...,int,coding,tot,leq,枚举,include,517 来源: https://www.cnblogs.com/ljc20020730/p/11180005.html