C题:一道简单的C题卡了半天,我太菜了
题意:给你一个n*2的矩阵,每个位置有一个数字,对应一种管道,要求通道可不可以从左上通到右下
由提议可以看出,1,2对应的是直管道,3,4,5,6对应弯管道,只有弯管道成对才可以换行,直管道只能换列
只需直管道的时候往右走,弯管的时候判断一下对应的下一行情况,同时弯管就换行,不是就输出“NO”
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstring> 3 #include <string> 4 #include <cmath> 5 #include <algorithm> 6 7 using namespace std; 8 typedef long long ll; 9 string s[3]; 10 11 int main() 12 { 13 int q; 14 cin >> q; 15 while(q--) 16 { 17 int n; 18 bool flag =false; 19 cin >> n; 20 cin >> s[0]>>s[1]; 21 int num =0; 22 int i=0; 23 int j=0; 24 while(i<n) 25 { 26 if(s[j][i]<'3')i++; 27 else if(s[j][i]>'2') 28 { 29 j^=1; 30 if(s[j][i]>'2')i++; 31 else{ 32 break; 33 } 34 } 35 } 36 if(j==1&&i==n) 37 { 38 cout <<"YES"<<endl; 39 } 40 else{ 41 cout <<"NO"<<endl; 42 } 43 } 44 return 0; 45 }
D题
题意:给你一个字符串,然后有q次操作,操作分为两种:第一种操作是改变一个位置的字母为另一个指定字母;第二种操作是查询区间(L~R)上有多少个不同的字符
思路:第一想法是线段树模板,线段树一直还没看,也没有看板子,当时就没有做,后来补题看别人交的代码,发现竟然可以用set来优化查询,果然我就连STL都不会用,留下菜的泪水。。。。。。。
就是我们字母总共就只有26个,我就开26个set来存,每个字母的位置,修改时只需将那个点的字母去掉那个位置,在给定的字母里面加上这个为位置,查询时就将26个字母都查一遍
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstring> 3 #include <string> 4 #include <algorithm> 5 #include <cmath> 6 #include <set> 7 using namespace std; 8 typedef long long ll; 9 10 int main() 11 { 12 string s; 13 set<int>p[26]; 14 cin >> s; 15 for(int i=0;i<s.size();i++) 16 { 17 p[s[i]-'a'].insert(i+1); 18 } 19 int q; 20 cin >> q; 21 while(q--) 22 { 23 int a; 24 scanf("%d",&a); 25 if(a==1){ 26 int b; 27 char cc[2]; 28 scanf("%d",&b); 29 scanf("%s",cc); 30 //cout <<cc[0]<<endl; 31 p[s[b-1]-'a'].erase(b); 32 s[b-1]=cc[0]; 33 p[cc[0]-'a'].insert(b); 34 35 } 36 else{ 37 int l,r; 38 int ans = 0; 39 scanf("%d%d",&l,&r); 40 for(int i=0;i<26;i++) 41 { 42 if(p[i].size()) 43 { 44 auto j =p[i].lower_bound(l); 45 if(*j<=r&&j!=p[i].end())ans++; 46 } 47 } 48 cout << ans<<endl; 49 } 50 } 51 return 0; 52 }