1,2,3,4,5,6,7,8,9,10,11,12
1003考慮用bitset加速dp,本質上還是n^3的dp。bitset不能處理異或所以考慮把異或和作爲第一維,體積和作爲第二維。
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll read() { ll x;scanf("%lld",&x);return x; } bitset<1025>f[1025]; int n,m,w,v; void work() { n=read();m=read(); for(int i=0;i<=1024;i++) f[i].reset(); f[0][0]=1; for(int i=1;i<=n;i++) { v=read();w=read(); for(int j=0;j<=1024;j++) { if((j^w)<=1024) f[j]|=f[j^w]<<v; } } for(int i=1024;i>=1;i--) if(f[i][m]) { printf("%d\n",i); return ; } printf("-1\n"); } int main() { for(int t=read();t;t--) work(); }
1009考慮優雅的暴力。剛開始想到可以枚舉地雷的中心,用map預處理後判斷是否能炸掉所有敵人是O(log)的,那麼枚舉地雷的中心多少有點難辦。
我們考慮枚舉2到n號地雷,如果他們和1號敵人位於同一行或者同一列或者同一斜就continue,如果全滿足就把炸彈放在1號敵人處即可。如果出現不滿足條件的考慮用這兩個敵人枚舉炸彈所在位置,枚舉的過程即爲如果1號橫着被炸到i號豎着被炸到、1號橫着i號斜着被炸到等12種情況,用調換1i位置的方法還可以減少到6種。總之,在寫完1003一個小時之後總算調出來了(中間那個1003是隊友揹着我寫的我根本不知道他在寫)
1011是簽到題,大膽輸出(n-m)/2即可。
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll read() { ll x;scanf("%lld",&x);return x; } ll mod=1000000007; ll quick(ll a,ll b) { ll ans=1; for(;b;b>>=1,a=a*a%mod) if(b&1)ans=ans*a%mod; return ans%mod; } ll n,m; int main() { for(int t=read();t;t--) { n=read();m=read(); cout<<(n-m)*quick(2,mod-2)%mod<<endl; } }
1012是博弈論,考慮了一下只用一種數字應該怎樣贏之後很容易推到用多種數字,掃一遍即可。
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll read() { ll x;scanf("%lld",&x);return x; } ll a[1000010],sum,n; void work() { n=read(); for(int i=0;i<=n;i++) a[i]=read(); for(int i=n;i>=1;i--) a[i-1]+=a[i]/2; if(a[0]) cout<<"Alice\n"; else cout<<"Bob\n"; } int main() { for(int t=read();t;t--) work(); }