Codeforces Round #297 (Div. 2)
题目大意:小写字母是钥匙,大写字母是门,字母相同的钥匙能开对应的门,从第一个门走到最后一个门,问至少要配多少钥匙才能走到最后
思路:扫一遍记录当前拥有的钥匙即可,如果手上没有这种钥匙那么配一把
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #define maxn 200000 6 char ch[maxn]; 7 using namespace std; 8 int key[maxn]; 9 int main() 10 { 11 int n,ans=0; 12 scanf("%d",&n); 13 scanf("%s",ch+1); 14 for(int i=1;i<=n-1;i++) 15 { 16 key[ch[(i-1)*2+1]-'a']++; 17 int u=ch[(i-1)*2+2]-'A'; 18 if(key[u]>0)key[u]--;else ans++; 19 } 20 printf("%d\n",ans); 21 }
题目大意:一串字符s,每次一个翻转,将区间i 到 |s|-i+1反转,|s|表示s的长度,问最后的序列
思路:一开始想烦了,后来发现只要记录翻转区间的端点,然后一路扫过去,覆盖两次的显然不用改就行了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #define maxn 200009 6 using namespace std; 7 char ch[maxn]; 8 int pos[maxn]; 9 int main() 10 { 11 int m,x; 12 scanf("%s",ch+1); 13 int len=strlen(ch+1),ha=(len+1)>>1; 14 scanf("%d",&m); 15 for(int i=1;i<=m;i++) 16 { 17 scanf("%d",&x); 18 pos[x] ^= 1; 19 pos[len - x + 1]=pos[x]; 20 } 21 int flag=0; 22 for(int i=1;i<=ha;i++) 23 { 24 if(pos[i]==1)flag ^= 1; 25 if(flag==1)swap(ch[i],ch[len - i + 1]); 26 } 27 printf("%s\n",ch+1); 28 }
题目大意:一串木棍组成长方形,每根木棍允许被销去1单位长度,一个长方形只能被4根木棍组成,问组成的一系列长方形的最大面积是多少
思路:显然得把木棍排序后从大向小找,两个木棍长度越接近越好,于是从大到小枚举能组成长方形的两根木棍,一旦出现就拼成长方形
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #define maxn 200000 6 using namespace std; 7 int a[maxn]; 8 int cmp(int x,int y){return x>y;} 9 int abs(int x){if(x<0)return -x;return x;} 10 int check(int x,int y) 11 { 12 if(a[x]-a[x+1]>1 && a[y-1]-a[y]>1)return 0; 13 return a[x+1]*a[y]; 14 } 15 int main() 16 { 17 int n; 18 long long ans=0; 19 scanf("%d",&n); 20 for(int i=1;i<=n;i++)scanf("%d",&a[i]); 21 sort(a+1,a+1+n,cmp); 22 long long last=0; 23 for(int i=1;i<=n-1;i++) 24 { 25 if(a[i]-a[i+1]<=1) 26 { 27 if(last==0)last=a[i+1]; 28 else 29 { 30 ans +=(long long )last * a[i+1]; 31 last=0; 32 } 33 i++; 34 } 35 } 36 printf("%I64d\n",ans); 37 return 0; 38 }
题目大意:给一个长方形的房间,里面一些cell中有障碍,要使每个连通块都是长方形,且除去的障碍最少,给出最后方案
思路:显然每个2*2的cell如果只有1个格子有障碍那么那个障碍必定要清除的,那清除以后可能会对周围的cell产生影响,所以dfs一遍周围的格子
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<iostream> 3 #define maxn 3009 4 using namespace std; 5 char ch[maxn]; 6 int map[maxn][maxn],m,n; 7 void dfs(int x,int y) 8 { 9 int cnt=0; 10 if(x<1 || x >= n || y<1 || y>=m)return; 11 for(int i=0;i<=1;i++) 12 { 13 for(int j=0;j<=1;j++) 14 { 15 cnt+=map[x+i][y+j]; 16 } 17 } 18 if(cnt==1) 19 { 20 for(int i=0;i<=1;i++) 21 { 22 for(int j=0;j<=1;j++) 23 { 24 map[x+i][y+j]=0; 25 } 26 } 27 for(int i=-1;i<=1;i++) 28 { 29 for(int j=-1;j<=1;j++) 30 { 31 dfs(x+i,y+j); 32 } 33 } 34 } 35 } 36 int main() 37 { 38 scanf("%d%d",&n,&m); 39 for(int i=1;i<=n;i++) 40 { 41 scanf("%s",ch+1); 42 for(int j=1;j<=m;j++) 43 { 44 if(ch[j]=='*')map[i][j]=1; 45 } 46 } 47 for(int i=1;i<=n;i++) 48 { 49 for(int j=1;j<=m;j++) 50 { 51 dfs(i,j); 52 } 53 } 54 for(int i=1;i<=n;i++) 55 { 56 for(int j=1;j<=m;j++) 57 { 58 if(map[i][j]==1)printf("*"); 59 else printf("."); 60 } 61 puts(""); 62 } 63 return 0; 64 }