大模擬ios
#include <cstdio> #include <cstring> #include <iostream> using namespace std; const int xGo[4]={-1,0,1,0}; const int yGo[4]={0,-1,0,1}; int n,m,map[220][220][2]; int x,y,fOri,wOri,maxCilp,totCilp,cilp[32],bigBullet,smallBullet,k,endIf,totTarget; void IN_Map_Robot(); void OutPut(int); int Para(char str[]); void FortCom(char str[]); void WheelCom(char str[]); void EndCom(char str[]); int main() { freopen("robo.in","r",stdin); freopen("robo.out","w",stdout); int t; scanf("%d",&t); while(t--) { IN_Map_Robot(); while(k--) { char str[10]; cin.getline(str,10); if(endIf) continue; if(str[0]=='F') FortCom(str); if(str[0]=='W') WheelCom(str); if(str[0]=='E') EndCom(str); } if(!endIf) OutPut(0); } fclose(stdin); fclose(stdout); return 0; } void IN_Map_Robot() { memset(map,0,sizeof(map)); totCilp=0,fOri=0,wOri=0,endIf=0,totTarget=0; scanf("%d%d",&n,&m); for(int i=0;i<n;++i) for(int j=0;j<m;++j) scanf("%d ",&map[i][j][0]); scanf("%d %d %d %d %d %d\n",&x,&y,&maxCilp,&bigBullet,&smallBullet,&k); } void FortCom(char str[]) { if(str[1]=='T') { int par=Para(str+3); if(par==0) fOri=(fOri+1)%4; else if(par==1) fOri=(fOri+3)%4; else { OutPut(0); return ; } } if(str[1]=='F') { int par=Para(str+3); if((par==0&&smallBullet==0)||(par==1&&bigBullet==0)) return; if(par==0&&totCilp<maxCilp) cilp[++totCilp]=par,smallBullet--; else if(par==1&&totCilp<maxCilp) cilp[++totCilp]=par,bigBullet--; else { OutPut(0); return ; } } if(str[1]=='E') { if(totCilp==0) return ; int nx,ny; for(int i=1;;++i) { nx=x+xGo[fOri]*i,ny=y+yGo[fOri]*i; if(nx<0||nx>=n||ny<0||ny>=m) break; if(map[nx][ny][0]==1||map[nx][ny][0]==2) break; } totCilp--; if(nx<0||nx>=n||ny<0||ny>=m) return ; if(map[nx][ny][0]==1) return ; if(cilp[totCilp+1]||map[nx][ny][1]) { map[nx][ny][0]=0; totTarget++; } else map[nx][ny][1]=1; } } void WheelCom(char str[]) { if(str[1]=='T') { int par=Para(str+3); if(par==0) wOri=(wOri+1)%4; else if(par==1) wOri=(wOri+3)%4; else { OutPut(0); return ; } } else { int par=Para(str+3); int nx=x+xGo[wOri]*par,ny=y+yGo[wOri]*par; if(nx<0||nx>=n||ny<0||ny>=m) { OutPut(0); return ; } else { for(int i=1;i<=par;++i) { nx=x+xGo[wOri]*i,ny=y+yGo[wOri]*i; if(map[nx][ny][0]) { OutPut(0); return ; } } } x=nx,y=ny; } } void EndCom(char str[]) { OutPut(1); } void OutPut(int type) { endIf=1; if(type) printf("Complete\n"); else printf("ERROR\n"); printf("%d %d\n",x,y); printf("%d\n",totTarget); printf("%d %d %d %d\n",fOri,wOri,bigBullet,smallBullet); } int Para(char str[]) { int i,re=0; for(i=0;;++i) { if(str[i]=='.') return 114514; if(str[i]=='\0') break; } i=0; do { re=re*10+(str[i]-'0'); i++; }while(str[i]!='\0'); return re; }
DFS 搜出,路徑,一樣長度可是膨脹程度不同 c++
狀壓DP+BFSspa
f[s][i]------(+dis[i][j])------->f[s|(1<<j)][j] 3d
#include <bits/stdc++.h> using namespace std; const int N=505,M=505,K=15; const int dx[4]={0,0,1,-1}; const int dy[4]={1,-1,0,0}; const char* st[4]={"R","L","D","U"}; int Path[(N+M)<<1],n,m,S; int mp[N][M]; void Read_Map() { scanf("%d%d%d",&n,&m,&S); for (int i=0;i<n;++i) for (int j=0;j<m;++j) scanf("%d",&mp[i][j]);//mp=0爲可行,不然爲障礙 } queue<pair<int,int> >Q; int Path_[K+1][K+1][(N+M)<<1],dist[K+1][K+1],szt[K+1][K+1]; int dis[K][1<<K],sum[K][1<<K]; pair<int,int> pre[K][1<<K]; void Put_Path(int *Path,int &len,int begin,int end) { for (int i=0;i<dist[begin][end];++i) Path[len++]=Path_[begin][end][i]; } bool CoordValid(int x,int y) { return x>=0 && x<n && y>=0 && y<m; } bool CoordValid(int x,int y,int size) { for (int i=-size;i<=size;++i) for (int j=-size;j<=size;++j) if (!CoordValid(x+i,y+j) || mp[x+i][y+j]==1) return 0; return 1; } int Size(int x,int y) { for (int i=S;i>=0;--i) if (CoordValid(x,y,i)) return i; return -1; } int pree[N][M],diss[N][M],sz[N][M]; void FindPath(int *ax,int *ay,int count) { for (int i=0;i<count;++i) { Q.push(make_pair(ax[i],ay[i])); memset(pree,0,sizeof(pree)); memset(diss,0x7f,sizeof(diss)); memset(sz,0,sizeof(sz)); diss[ax[i]][ay[i]]=0; while (!Q.empty()) { pair<int,int> u=Q.front(); Q.pop(); for (int i=0;i<4;++i) { int tx=u.first+dx[i],ty=u.second+dy[i],s=Size(tx,ty); if (s!=-1 && (diss[tx][ty]>diss[u.first][u.second]+1 || (diss[tx][ty]==diss[u.first][u.second]+1 && sz[u.first][u.second]+s>sz[tx][ty]))) { diss[tx][ty]=diss[u.first][u.second]+1; pree[tx][ty]=i; sz[tx][ty]=sz[u.first][u.second]+s; Q.push(make_pair(tx,ty)); } } } for (int j=0;j<count;++j) { dist[i][j]=diss[ax[j]][ay[j]]; szt[i][j]=sz[ax[j]][ay[j]]; // int len=0,nowx=ax[j],nowy=ay[j]; // while (nowx!=ax[i] || nowy!=ay[i]) { // Path_[i][j][len++]=pree[nowx][nowy]; // int px=nowx-dx[pree[nowx][nowy]],py=nowy-dy[pree[nowx][nowy]]; // nowx=px; nowy=py; // } // reverse(Path_[i][j],Path_[i][j]+len); } } } void Planning(int now_x,int now_y,int *aim_x,int *aim_y,int count_aim,int *Path,int &len) { aim_x[count_aim]=now_x; aim_y[count_aim]=now_y; FindPath(aim_x,aim_y,count_aim+1); int Mx=1<<count_aim; for (int i=0;i<=count_aim;++i) for (int j=0;j<Mx;++j) pre[i][j]=make_pair(-1,-1),dis[i][j]=1<<30; for (int i=0;i<count_aim;++i) dis[i][(Mx-1)^(1<<i)]=0,sum[i][(Mx-1)^(1<<i)]=0; for (int i=0;i<count_aim;++i) for (int j=Mx-1;j>=0;--j) for (int k=0;k<count_aim;++k) if (i!=k && !((j>>k)&1) && (dis[i][j]>dis[k][j^(1<<i)]+dist[i][k] || ( dis[i][j]==dis[k][j^(1<<i)]+dist[i][k] && sum[i][j]<sum[k][j^(1<<i)]+szt[i][k] ) )) { dis[i][j]=dis[k][j^(1<<i)]+dist[i][k]; sum[i][j]=sum[k][j^(1<<i)]+szt[i][k]; pre[i][j]=make_pair(k,j^(1<<i)); } int mn=0,v=0; len=0; for (int i=1;i<count_aim;++i) if (dis[i][v]+dist[count_aim][i]<dis[mn][v]+dist[count_aim][mn] || (dis[i][v]+dist[count_aim][i]==dis[mn][v]+dist[count_aim][mn] && sum[i][v]+szt[count_aim][i]>sum[mn][v]+szt[count_aim][mn])) mn=i; printf("%d %d\n",dis[mn][v]+dist[count_aim][mn],sum[mn][v]+Size(now_x,now_y)+szt[count_aim][mn]); /* for (int i=1;i<count_aim;++i) if (dis[i][v]+dist[count_aim][i]<dis[mn][v]+dist[count_aim][mn]) mn=i; Put_Path(Path,len,count_aim,mn); while (pre[mn][v].first!=-1) { pair<int,int> u=pre[mn][v]; Put_Path(Path,len,mn,u.first); mn=u.first; v=u.second; } */ } int main() { freopen("expand.in","r",stdin); freopen("expand.out","w",stdout); Read_Map(); int now_x,now_y,aim_x[K],aim_y[K],count_aim; scanf("%d%d%d",&now_x,&now_y,&count_aim); for (int i=0;i<count_aim;++i) scanf("%d%d",&aim_x[i],&aim_y[i]); int len=0; Planning(now_x,now_y,aim_x,aim_y,count_aim,Path,len); // for (int i=0;i<len;++i) // printf("%s",st[Path[i]]); putchar('\n'); fclose(stdin); fclose(stdout); return 0; } /* input: 4 6 3 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 1 3 0 output: 7 5 */
20 20 152 3 26 133 54 79 81 72 109 66 91 82 100 35 23 104 17 51 114 12 58 2 1 17 2 6 12 1 1 12 2 3 5 2 11 11 2 7 19 2 6 15 1 5 12 1 1 9 1 10 19 2 3 19 2 6 20 2 1 13 2 1 15 2 1 9 1 1 1 2 1 7 2 7 19 2 6 19 2 3 6
Yes
Yes
Yes
Yes
No
(圖右半邊是折半搜索)code
解釋一哈:blog
由於區間內的每一個小盆友均可以有選或者不選兩種狀況,因此一共有2len 種ci
因此該區間的子集種類數:有2len 種get
子集和的範圍:0~v*leninput
2len 種子集本應該是與v*len一一映射的string
可是當2len > v*len 時,
集合的取值必定會有重複的,因此此時必定有解
解得 len>=14
∴len<14時要折半搜索
由於以前處理過 len<=7 的狀況
那麼有重複的怎麼辦???
其實不影響
好比序列 1 1 3 2
所選集合有重疊,可是他們相等,那麼去掉重複的以後也是相等的
# include <iostream> # include <cstdio> # include <cstring> # include <cstdlib> using namespace std; const int V = 1e3 + 10; const int N = 1e5 + 12; int read() { int ans = 0,f = 1; char i = getchar(); while(i < '0' || i > '9'){if(i == '-')f = -1;i = getchar();} while(i >= '0' && i <= '9'){ans = ans * 10 + i - '0';i = getchar();} return ans * f; } int n,m,v,mid,ol,x,y,d; int data[V][22],a[N],stack[N],cnt; int sum[N << 2],lazy[N << 2]; bool flag[N]; void down(int rt){ lazy[rt << 1] += lazy[rt]; lazy[rt << 1 | 1] += lazy[rt]; lazy[rt] = 0; } void push(int &ans,int &r){ int j = 20; while(j >= 0){ if(r >= (1 << j)){ ans = data[ans][j]; r -= (1 << j); if(r == 0)return; } j--; } } void updata(int L,int R,int l,int r,int rt){ if(L <= l && r <= R){ lazy[rt]++; return; } if(lazy[rt])down(rt); int mid = (l + r) >> 1; if(L <= mid)updata(L,R,l,mid,rt << 1); if(R > mid)updata(L,R,mid + 1,r,rt << 1 | 1); return; } void Query(int L,int l,int r,int rt){ if(l == r){ push(a[L],lazy[rt]); return; } if(lazy[rt])down(rt); int mid = (l + r) >> 1; if(L <= mid)Query(L,l,mid,rt << 1); else Query(L,mid + 1,r,rt << 1 | 1); return; } void init(){ for(int i = 0;i < v;i++){ data[i][0] = (i * i % v) * i % v; } for(int j = 1;j <= 20;j++){ for(int i = 0;i < v;i++){ data[i][j] = data[data[i][j - 1]][j - 1]; } } } void dfsl(int u,int dis,bool k){ if(ol)return; if(u == mid + 1){ if(k){ if(!dis){ ol = true; }else if(dis >= 0 && !flag[dis]){flag[dis] = true;stack[++cnt] = dis;} } return; } dfsl(u + 1,dis,k); dfsl(u + 1,dis + a[u] + 1,true); dfsl(u + 1,dis - a[u] - 1,true); return; } void dfsr(int u,int dis,bool k){ if(ol)return; if(u == y + 1){ if(k){ if(!dis){ ol = true; }else if(dis >= 0 && flag[dis]){ ol = true; } } return; } dfsr(u + 1,dis,k); dfsr(u + 1,dis + a[u] + 1,true); dfsr(u + 1,dis - a[u] - 1,true); return; } int main(){ freopen("birthday.in","r",stdin); freopen("birthday.out","w",stdout); n = read(),m = read(),v = read(); for(int i = 1;i <= n;i++)a[i] = read(); init(); for(int i = 1;i <= m;i++){ d = read(),x = read(),y = read(); if(d == 2){ updata(x,y,1,n,1); }else { if(y - x >= 13){ puts("Yes"); }else { for(int j = x;j <= y;j++){ Query(j,1,n,1); } mid = (x + y) >> 1; ol = false;cnt = 0; dfsl(x,0,false); dfsr(mid + 1,0,false); for(int i = 1;i <= cnt;i++){ flag[stack[i]] = false; } if(ol)puts("Yes");else puts("No"); } } } fclose(stdin); fclose(stdout); return 0; }