Consonant Fencity Gym - 101612C 暴力二進位制列舉 Intelligence in Perpendicularia Gym - 101612I 思維
阿新 • • 發佈:2020-11-14
題意1:
給你一個由小寫字母構成的字串s,你可以其中某些字元變成大寫字母。如果s中有字母a,你如果想把a變成大寫,那s字串中的每一個a都要變成A
最後你需要要出來所有的字元對,s[i]和s[i-1]需要是子音字母,且s[i]和s[i-1]中需要一個字母大寫另一個小寫。a、e、i、o、u、w、y這七個字母是母音
輸出最大字元對數量
題解1:
首先預處理一下s字串中字元相鄰的數量,就是記錄w[s[i-1]][s[i]]的數量
之後二進位制列舉所有字母變成大寫的情況。
然後列舉這個字母變成大寫之後和其他字母組成成為字元對的數量。也就是結果加上w[x][k](x是變成大寫的字母,k是列舉x和那個字母組成字元對)
那麼如果b和c在s字串中相鄰了,然後b和c都變成大寫怎麼處理?
列舉到b變成大寫的時候,x='b',當k='c'這個時候需要加上w[x][k]。
到下一次列舉到c的時候,x='c',當k='b'我們判斷k是否變成了大寫,如果變了,就減去w[x][k]
AC程式碼:
#include <algorithm> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <iostream> #include<map> #include <queue> #include <set> #include <vector> using namespace std; typedef long long ll; const int maxn = 1e6 + 5; const int mod = 1000000007; char s[maxn]; int w[150][150],que[150],vis[150]; int main() { freopen("consonant.in","r",stdin); freopen("consonant.out","w",stdout); scanf("%s",s); int len=strlen(s); if(len==1) { printf("%s\n",s); return 0; } for(int i=1;i<len;++i) { w[s[i-1]][s[i]]++; } int pos=0; for(int i='a';i<='z';++i) { if(i=='a' || i=='e' || i=='o' || i=='u' || i=='i' || i=='w' || i=='y') continue; que[pos++]=i; } //printf("%d***\n",pos); int ans=0,flag=0; for(int i=0;i<(1<<pos);++i) { int sum=0; memset(vis,0,sizeof(vis)); for(int j=0;j<pos;++j) { if((1<<j)&i) { for(int k='a';k<='z';++k) { if(k=='a' || k=='e' || k=='o' || k=='u' || k=='i' || k=='w' || k=='y' || k==que[j]) continue; if(vis[k]) { // if(i==1026) // { // printf("********%c %c %d %d\n",k,que[j],w[k][que[j]],w[que[j]][k]); // } sum-=w[k][que[j]]; sum-=w[que[j]][k]; } else { // if(i==1026) // { // printf("%c %c %d %d\n",k,que[j],w[k][que[j]],w[que[j]][k]); // } sum+=w[k][que[j]]; sum+=w[que[j]][k]; } } vis[que[j]]=1; } } if(ans<sum) { ans=sum; flag=i; } // printf("%d***\n",sum); // system("pause"); } memset(vis,0,sizeof(vis)); for(int i=0;i<pos;++i) { if((1<<i)&flag) { vis[que[i]]=1; } } for(int i=0;i<len;++i) { if(vis[s[i]]) printf("%c",s[i]-32); else printf("%c",s[i]); } printf("\n"); return 0; }
題意2:
按順序給你n個點,表示第i個點和第i-1個點相連,第1個點和第n個點相連。
題目保證所有連線和x或者y軸平行。讓你輸出n個點構成的圖形看不到區域的長度
題解:
首先設這n個點構成的圖形周長為x,後面使用x-大矩形周長就是答案
大矩形周長:就是把圖形補全之後的外層大矩形的周長
程式碼:
#include <algorithm> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <iostream> #include <map> #include <queue> #include <set> #include <vector> using namespace std; typedef long long ll; const int maxn = 1e3 + 5; const int INF=0x3f3f3f3f; const int mod = 1000000007; struct Node { int x,y; }node[maxn]; int main() { freopen("intel.in","r",stdin); freopen("intel.out","w",stdout); int n; scanf("%d",&n); for(int i=1;i<=n;++i) { scanf("%d%d",&node[i].x,&node[i].y); } int ans=0,minnx=INF,minny=INF,maxxx=0,maxxy=0; node[n+1]=node[1]; for(int i=2;i<=n+1;++i) { minnx=min(minnx,node[i].x); minny=min(minny,node[i].y); maxxx=max(maxxx,node[i].x); maxxy=max(maxxy,node[i].y); if(node[i-1].x==node[i].x) { ans+=abs(node[i].y-node[i-1].y); } else if(node[i-1].y==node[i].y) { ans+=abs(node[i].x-node[i-1].x); } } printf("%d\n",ans-((maxxx-minnx)*2+(maxxy-minny)*2)); return 0; } /* 10 1 1 6 1 6 4 3 4 3 3 5 3 5 2 2 2 2 3 1 3 */