Sharding Sphere的分庫分表
A Kids Seating
題意:有n個小朋友,有4 * n把編號1~4 * n的椅子,每個小朋友不能坐在編號gcd==1的位置
思路:輸出2 * n~4 * n之間的n個偶數
B Saving the City
題意:給一串01字元,1表示地雷,現在有兩個費用,安置地雷a元(把0變成1),引爆地雷b元,地雷爆發會導致相鄰的所有地雷爆炸,問最少輸出多少錢
思路:找兩個1聯通塊中間的0的個數num,求num * b+a和2 * a的大小,小的話就是加上一個num * b-a,每個1的聯通塊都要+a
#include<bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof(a)) #define ll long long #define lson(x) x<<1 #define rson(x) x<<1|1 using namespace std; const int N=1e5+10; int a,b; char s[N]; int zhi[N]; int main(){ int t; scanf("%d",&t); while(t--){ scanf("%d%d",&a,&b); scanf("%s",s); int l=strlen(s); int sum=0,num1=0,num0=0; int i=0; s[l]='0'; for(i=0;i<l;i++){ if(s[i]=='1'){ break; } } int cnt=0; for(;i<l;i++){ if(s[i]=='1'&&s[i+1]=='0'){ zhi[cnt++]=num1+1;num1=0; } else if(s[i]=='0'&&s[i+1]=='1'){ zhi[cnt++]=num0+1;num0=0; } else if(s[i]=='1'&&s[i+1]=='1'){ num1++; } else{ num0++; } } for(int i=0;i<cnt;i++){ if(i&1 && i!=cnt-1){ if(zhi[i]*b+a<2*a){ sum+=(zhi[i]*b-a); } } else{ sum+=a; } } printf("%d\n",sum); } return 0; }
C The Delivery Dilemma
題意:你有n個菜,可以選擇叫外賣去拿外賣送家裡和去店拿外賣。外賣去拿的外賣算最大的,自己去店裡拿需要求和,問你拿完這個n個菜,最少時間是多少
思路:按照叫外賣從小到大排序,自己去拿字首和,然後o(n)方法比較即可。
#include<bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof(a)) #define ll long long #define lson(x) x<<1 #define rson(x) x<<1|1 using namespace std; const int N=2e5+10; int n; struct node{ int a,b; friend bool operator<(const node a,const node b){ if(a.a==b.a){ return a.b<b.b; } return a.a<b.a; } }a[N]; ll ans[N]; int main(){ int t; scanf("%d",&t); while(t--){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&a[i].a); } for(int i=1;i<=n;i++){ scanf("%d",&a[i].b); } sort(a+1,a+n+1); ans[0]=0; for(int i=1;i<=n;i++){ ans[i]=a[i].b+ans[i-1]; } ll mix=1e15; for(int i=1;i<=n;i++){ mix=min(mix,max((ll)a[i].a,ans[n]-ans[i])); } mix=min(mix,ans[n]);//特判全部自己拿的情況 printf("%lld\n",mix); } return 0; }
D Extreme Subtraction
題意:給你一個n長度的陣列,問有兩種操作,選擇一個k,1 ~ k下標陣列值-1或者k ~ n下標陣列值,問能不能使得陣列全部為0,能輸出yes,不能no
思路:從前算後面能否形成遞減序列,或者從後算前面能否形成遞增序列
給wa的盆友兩個樣例
2
6
5 3 5 2 4 3
6
5 3 5 3 4 3
yes
no
#include<bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof(a)) #define ll long long #define lson(x) x<<1 #define rson(x) x<<1|1 using namespace std; const int N=3e4+10; int n; int a[N],b[N],c[N]; int main(){ int t; scanf("%d",&t); while(t--){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); int f=1; int ans=0,minl=1e9; for(int i=n;i>=1;i--){ a[i]-=ans; if(a[i]<0) f=0,break; if(a[i]<=minl) minl=a[i]; else ans+=(a[i]-minl); } if(f) printf("YES\n"); else printf("NO\n"); } return 0; }
E 留坑待補
F Identify the Operations
題意:給你n,m長度的兩個陣列(分為a,b),某人得到了長度為n的陣列(1~n無序排列的陣列),有m個操作,刪除一個n長度中的一個數字,把這個數字的前一個或者後一個(第一位和最後一位只能選一個),按照操作順序放進另一個數組裡,問有多少種情況能的到m長度的陣列,答案取模
思路:標記a組數字在陣列的位置,用pos陣列存在b組每個數在a組的位置,並存進map裡。for一遍,如果這個點的前、後下標在map裡出現的則答案為0,如果這個點只出現過前或者後 * 1,都沒出現過則 * 2,特判一下第一個和最後一個。然後把這個點從map中刪除
#include<bits/stdc++.h>
using namespace std;
#define mod 998244353
#define ll long long
const int N=2e5+10;
int a[N],b[N],pos[N],cnt[N];
int n,m;
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
map<int,int>mp;
for(int i=0;i<n;i++)scanf("%d",&a[i]),pos[a[i]]=i;
for(int i=0;i<m;i++)scanf("%d",&b[i]),cnt[i]=pos[b[i]],mp[pos[b[i]]]++;
ll ans=1;
for(int i=0;i<m;i++){
if(cnt[i]==0){
if(mp[1]){ans=0;}
mp[0]--;
}
else if(cnt[i]==n-1){
if(mp[n-2]){ans=0;}
mp[n-1]--;
}
else{
ll k=2;
if(mp[cnt[i]-1])k--;
if(mp[cnt[i]+1])k--;
ans*=k;ans%=mod;
mp[cnt[i]]--;
}
}
printf("%lld\n",ans);
}
return 0;
}
老年人了,要早睡早起(偷懶),於是開了模擬去做,做完這套感覺就是,div2就這???感覺在寫div3一樣 算了模擬賽卡了D,賽後看了F,想不出好方法,模擬了一遍居然AC了!
多努力才能少打鐵,鍛鍊自己的心態也很重要。希望別留遺憾吧