A.簡單題(kmp)鏈接
解法:把每個壓縮的字符展開,然後kmp即可
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cassert>
using namespace std ;
const int N = 1e6 + 11 ;
const int M = 1e3 + 11 ;
char str1[N] , str2[M] ;
int len1 , len2 ;
char ss[M] ;
int jump[M] ;
void getjump() {
int i = 0 , j = -1 ;
jump[0] = -1 ;
while(i < len2) {
if(j == -1 || str2[i] == str2[j]) {
++i , ++j ;
jump[i] = j ;
}else j = jump[j] ;
}
}
bool check() {
getjump() ;
int i = 0 , j = 0 ;
while(i < len1) {
if(j == -1 || str1[i] == str2[j]) {
++i , ++j ;
if(j >= len2) return true ;
}else j = jump[j] ;
}
return false ;
}
int main() {
//freopen("data.in" , "r" , stdin) ;
while(scanf("%s %s" , ss , str2)==2) {
int cnt = 0 ;
len1 = strlen(ss) ;
len2 = strlen(str2) ;
for(int i = 0 ; i < len1 ; ++i) {
if(ss[i] >= 'a' && ss[i] <= 'z') {
str1[cnt++] = ss[i] ;
}else {
int ret = 0 ;
int id = i+1 ;
while(ss[id] != ']') {
ret *= 10 ;
ret += ss[id] - '0' ;
id++ ;
}
char tmp = ss[i-1] ;
i = id ;
if(ret > len2) ret = len2 ;
while(ret--) {
str1[cnt++] = tmp ;
}
}
}
len1 = cnt ;
if(check()) printf("True\n") ;
else printf("False\n") ;
}
}
B.逆序數還原(樹狀數組+二分)鏈接
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cassert>
using namespace std ;
const int N = 1e3 + 11 ;
int arr[N] ;
int n ;
int lowbit(int x) {
return (x&-x) ;
}
void update(int x ,int d) {
for(int i = x ; i <= n ; i += lowbit(i)) {
arr[i] += d ;
}
}
int query(int x) {
int ans = 0 ;
for(int i = x ; i > 0 ; i -= lowbit(i)) {
ans += arr[i] ;
}
return ans ;
}
void init() {
memset(arr , 0 , sizeof(arr)) ;
for(int i = 1 ; i <= n ;++i) {
update(i , 1) ;
}
}
int fun(int x) {
int l = 1 , r = n ;
int mid , f ;
while(l < r) {
mid = (l+r)>>1 ;
f = query(mid) ;
if(f >= x) r = mid ;
else l = mid+1 ;
}
update(r , -1) ;
return r ;
}
int main() {//freopen("data.in" , "r" , stdin) ;
while(scanf("%d" ,&n)==1) {
init() ;
int a ;
for(int i = 1 ; i <= n ; ++i) {
scanf("%d" ,&a) ;
printf("%d" , fun(a+1));
if(i == n) printf("\n") ;
else printf(" ") ;
}
}
}
C.樹的路徑覆蓋鏈接
D.小明的迷宮鏈接
E.回家種地(掃描線)鏈接
求覆蓋大於一次的面積
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cassert>
using namespace std ;
const int N = 2e5 + 11 ;
typedef long long LL ;
struct Line {
int x1 , x2 , h , d ;
Line(){}
Line(int a ,int b , int c , int dd) {
x1 = a , x2 = b , h = c , d = dd ;
}
friend bool operator<(const Line& a , const Line& b) {
return a.h < b.h ;
}
};
int n ;
Line line[N] ; int nline ;
int num[N] ; int nn ;
struct Segment {
int w0[N<<2] , w1[N<<2] ;
int len[N<<2] ;
int cover[N<<2] ;
int x1 , y1 ;
int n ;
void init(int x) {
n = x ;
build(1 , 1 , n) ;
}
void up(int u) {
int lson = u<<1 , rson = u<<1|1 ;
if(cover[u] > 1) {
w0[u] = w1[u] = len[u] ;
}else if(cover[u] == 1) {
w1[u] = w0[lson] + w0[rson] ;
w0[u] = len[u] ;
}else {
w1[u] = w1[lson] + w1[rson] ;
w0[u] = w0[lson] + w0[rson] ;
}
}
void build(int u , int l , int r) {
cover[u] = 0 ;
if(l+1 == r) {
len[u] = num[r-1]-num[l-1] ;
w0[0] = w1[0] = 0 ;
return ;
}
int mid = (l+r)>>1 ;
build(u<<1 , l , mid) ;
build(u<<1|1 , mid , r) ;
len[u] =len[u<<1] + len[u<<1|1] ;
up(u) ;
}
void update(int l , int r , int d) {
x1 = l , y1 = r ;
_update(1 , 1 , n , d) ;
}
void _update(int u , int l , int r , int d) {
if(x1 <= l && r <= y1) {
cover[u] += d ;
if(l+1 == r) {
if(cover[u] > 1) {
w1[u] = w0[u] = len[u] ;
}else if(cover[u] == 1) {
w1[u] = 0 ;
w0[u] = len[u] ;
}else {
w1[u] = w0[u] = 0 ;
}
}else {
up(u) ;
}
return ;
}
int mid = (l+r)>>1 ;
if(x1 < mid) _update(u<<1 , l , mid , d) ;
if(y1 > mid) _update(u<<1|1 , mid , r , d) ;
up(u) ;
}
}seg;
void init() {
int x1 , y1 , x2 , y2 ;
nline = nn = 0 ;
for(int i = 1 ; i <= n ; ++i) {
scanf("%d %d %d %d" , &x1 , &y1 , &x2 , &y2) ;
line[nline++] = Line(x1 , x2 , y1 , 1) ;
line[nline++] = Line(x1 , x2 , y2 , -1) ;
num[nn++] = x1 , num[nn++] = x2 ;
}
sort(line , line+nline) ;
sort(num , num+nn) ;
nn = unique(num , num+nn)-num ;
}
int at(int x) {
return lower_bound(num , num+nn , x)-num+1 ;
}
void work() {
seg.init(nn) ;
int last = line[0].h ;
LL area = 0 ;
for(int i = 0 ; i < nline ; ++i) {
area += (LL)(seg.w0[1] - seg.w1[1])*(line[i].h-last) ;
last = line[i].h ;
seg.update(at(line[i].x1) , at(line[i].x2) , line[i].d) ;
}
printf("%I64d\n" , area) ;
}
int main() {
//freopen("data.in" , "r" ,stdin) ;
int t , tt = 0;
scanf("%d" ,&t) ;
while(t--) {
printf("Case %d: " , ++tt);
scanf("%d" ,&n) ;
init() ;
work() ;
}
}
F.過河I(bfs)鏈接
解法:bfs ,注意當羊爲0的時候,狼可以大於羊;每次必須運送大於1只動物
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
#include <cassert>
using namespace std ;
bool vis[201][201][2] ;
struct Node {
int wolf , sheep ;
int t ;
bool side ;
};
int x , y , n ;
void work() {
if(y > x && x != 0) {printf("-1\n") ; return ;}
memset(vis , 0 , sizeof(vis)) ;
Node fro ;
fro.wolf = y , fro.sheep = x , fro.side = false;
fro.t = 0 ;
vis[x][y][0] = true ;
queue<Node> que ;
que.push(fro) ;
while(!que.empty()) {
//cout<<fro.sheep<<" "<<fro.wolf<<" "<<fro.side<<endl;
fro = que.front() ;
que.pop() ;
if(fro.sheep == 0 && fro.wolf == 0 && fro.side == false || fro.sheep == x && fro.wolf == y && fro.side == true) {
printf("%d\n" , fro.t) ;
return ;
}
++fro.t ;
int wolf = fro.wolf , sheep = fro.sheep ;
int other_wolf = y - wolf , other_sheep = x - sheep ;
for(int i = 1 ; i <= sheep ; ++i) {
for(int j = 0 ; j <= wolf && j <= i&& (i+j)<= n ; ++j) {
if(sheep-i != 0 && sheep-i < wolf-j) continue ;
if(other_sheep+i < other_wolf+j) continue ;
Node tmp ; tmp.t = fro.t ;
tmp.sheep = other_sheep+i , tmp.wolf = other_wolf+j , tmp.side = !fro.side ;
if(vis[tmp.sheep][tmp.wolf][tmp.side]) continue ;
vis[tmp.sheep][tmp.wolf][tmp.side] = true ;
que.push(tmp) ;
}
}
for(int j = 1 ; j <= wolf && j <= n ; ++j) {
if(sheep != 0 && sheep < wolf-j) continue ;
if(other_sheep != 0 && other_sheep < other_wolf+j) continue ;
Node tmp ; tmp.t = fro.t ;
tmp.sheep = other_sheep , tmp.wolf = other_wolf+j , tmp.side = !fro.side ;
if(vis[tmp.sheep][tmp.wolf][tmp.side]) continue ;
vis[tmp.sheep][tmp.wolf][tmp.side] = true ;
que.push(tmp) ;
}
}
printf("-1\n") ;
}
int main() {
// freopen("data.in" ,"r" , stdin) ;
while(scanf("%d %d %d" ,&x , &y , &n)==3) {
work() ;
}
}