A
#include<cstdio>
int main(){
int a,b;
while(~scanf("%d %d",&a,&b)){
printf("%d\n",a+a-b);
}
return 0;
}
B 可以把點抽離出來,或者直接在50*50上bfs+dp。第一種複雜度更低
狀態壓縮+dp 當時可能想dp[S-1][0]一定是inf什麼的,腦子抽了。 我trick能力幾乎沒有啊…
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
#define inf 0x3f3f3f3f
int n,m;
int a[52][52],dis[11][11];
int x[11],y[11],cnt;
int dp[1<<11][11];
int main(){
while(cin>>n>>m){
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>a[i][j];
a[1][1]=1;
cnt=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(a[i][j]) x[cnt]=i,y[cnt]=j,cnt++;
for(int i=0;i<cnt;i++)
for(int j=0;j<cnt;j++)
dis[i][j]=abs(x[i]-x[j])+abs(y[i]-y[j]);
int S=1<<cnt;
memset(dp,inf,sizeof dp);
dp[1][0]=0;
for(int s=1;s<S;s++){
for(int j=0;j<cnt;j++){
if(dp[s][j]==inf) continue;
for(int k=0;k<cnt;k++){//j to k
if(s&(1<<k)) continue;
dp[s|(1<<k)][k]=min(dp[s|(1<<k)][k],dp[s][j]+dis[j][k]);
}
}
}
int ans=inf;
for(int i=0;i<cnt;i++)// my wa point i=1
ans=min(ans,dp[S-1][i]+dis[i][0]);
printf("%d\n",ans);
}
return 0;
}
/*
1 1
0
*/
C 題意是n層樓,每層有2個門到下一層的2個門,在同一層不能從 門1-門2
把一層樓看成一個點,a11 a12 表示第x層的門 i 到達下一層x+1的門 j 的情況數
a21 a22
x-y的情況數就是x-y-1 的 矩陣乘
由於是動態更新,在線查詢的,所以用線段樹(dan)維護矩陣區間
開始沒注意門編號是1或2,沒-1,對於細節應該更細心。
//19--57 40min
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL;
const int MOD=1000000007,N=50005;
struct Mat{
LL a[2][2];
Mat(){
memset(a,0,sizeof a);
}
void init(){
a[0][0]=a[1][1]=a[0][1]=a[1][0]=1;
}
void unit(){
a[0][0]=a[1][1]=1;
a[0][1]=a[1][0]=0;
}
Mat operator * (Mat b){
Mat c;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
c.a[i][j]=(c.a[i][j]+a[i][k]*b.a[k][j])%MOD;
return c;
}
};
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
Mat tree[N*4];
void push_up(int rt){
tree[rt]=tree[rt<<1]*tree[rt<<1|1];
}
void build(int l,int r,int rt){
if(l==r){
tree[rt].init();
return;
}
int m=(l+r)>>1;
build(lson);
build(rson);
push_up(rt);
}
Mat query(int a,int b,int l,int r,int rt){
//printf("%d %d %d %d %d--\n",a,b,l,r,rt);
if(a<=l&&b>=r){
return tree[rt];
}
Mat ret; ret.unit();
int m=(l+r)>>1;
if(a<=m) ret=ret*query(a,b,lson);
if(b>m) ret=ret*query(a,b,rson);
return ret;
}
void update(int x,int a,int b,int l,int r,int rt){
if(l==r){
tree[rt].a[a][b]^=1;
return;
}
int m=(l+r)>>1;
if(x<=m) update(x,a,b,lson);
else update(x,a,b,rson);
push_up(rt);
}
int n,m;
int main(){
int x,a,b,op;
while(cin>>n>>m){
build(1,n-1,1);
while(m--){
scanf("%d",&op);
if(op==0){
scanf("%d %d",&a,&b);
Mat ans=query(a,b-1,1,n-1,1);
printf("%d\n",(ans.a[0][0]+ans.a[0][1]+ans.a[1][0]+ans.a[1][1])%MOD);
}else{
scanf("%d %d %d",&x,&a,&b);//my wa point a,b 1-2
update(x,a-1,b-1,1,n-1,1);
}
}
}
return 0;
}
/*
one floor has two stairs. floor 1 to floor n has (n-1)*2 stairs.
be careful about -1
*/
D 官方說是AC自動機,看幾個A了的
好像是hash字符串的處理,以後補