May Challenge 2017
分析:水题,设置优先级,判断如果后面小于前面就输出no
1 #include "iostream" 2 #include "cstdio" 3 #include "cstring" 4 #include "string" 5 using namespace std; 6 const int maxn=10000+10; 7 string s; 8 int T; 9 int judge(char s){ 10 if(s=='C') 11 return 1; 12 else if(s=='E') 13 return 2; 14 else 15 return 3; 16 } 17 int main() 18 { 19 cin>>T; 20 while(T--){ 21 cin>>s; 22 int flag=0; 23 int len=s.length(); 24 for(int i=0;i<len-1;i++){ 25 if(judge(s[i])>judge(s[i+1])){ 26 flag=1; break; 27 } 28 } 29 if(flag) cout<<"no"<<endl; 30 else cout<<"yes"<<endl; 31 } 32 }
分析:简单DP,看上一个状态和当前状态的关系,如果先修课程数相同,则加1,否则取上一门课程加1和当前课程所需先修的最小值
1 #include "iostream" 2 #include "cstdio" 3 #include "cstring" 4 #include "string" 5 using namespace std; 6 const int maxn=100000+10; 7 int T; 8 int a[maxn]; 9 int dp[maxn]; 10 int main() 11 { 12 cin>>T; 13 while(T--) 14 { 15 int n; 16 cin>>n; 17 a[0]=0; 18 for(int i=1;i<=n;i++) 19 scanf("%d",&a[i]); 20 memset(dp,0,sizeof(dp)); 21 dp[1]=1; 22 for(int i=2;i<=n;i++){ 23 if(a[i]==a[i-1]) 24 dp[i]=dp[i-1]+1; 25 else{ 26 dp[i]=min((i-a[i]),dp[i-1]+1); 27 } 28 } 29 cout<<dp[n]<<endl; 30 } 31 return 0; 32 }
Median of adjacent maximum numbers
分析:水题,从大到小排,小的排在奇数位,大的排在偶数位即可
1 #include "iostream" 2 #include "cstdio" 3 #include "cstring" 4 #include "string" 5 #include "algorithm" 6 using namespace std; 7 const int maxn=50000*4+10; 8 int T,n; 9 int a[maxn]; 10 int main() 11 { 12 cin>>T; 13 while(T--){ 14 cin>>n; 15 for(int i=1;i<=2*n;i++) 16 cin>>a[i]; 17 sort(a+1,a+2*n+1); 18 int c[maxn]; 19 c[0]=0; 20 for(int i=1;i<=n;i++) 21 c[2*i-1]=a[i]; 22 for(int i=n+1;i<=2*n;i++) 23 c[2*(i-n)]=a[i]; 24 int b[maxn]; 25 b[0]=0; 26 for(int i=1;i<=n;i++){ 27 b[i]=max(c[2*i],c[2*i-1]); 28 } 29 cout<<b[n/2+1]<<endl; 30 for(int i=1;i<=2*n;i++) 31 cout<<c[i]<<" "; 32 cout<<endl; 33 } 34 return 0; 35 }
分析:很有意思的一道题,首先预处理一下每个位置往前的k个位置的有多少1,然后我们用线段树维护区间最大值即可,坑点比较多,一个是k>=n时候,还有一个是下标问题,容易RE
1 #include "iostream" 2 #include "cstdio" 3 #include "cstring" 4 #include "string" 5 #include "cmath" 6 #include "vector" 7 using namespace std; 8 const int maxn=4000000+10; 9 string t; 10 int n,k,p; 11 int dp[maxn]; 12 int a[maxn]; 13 int h[maxn]; 14 void init(string zz){ 15 if(zz[0]=='1') 16 dp[0]=1; 17 for(int i=1;i<k;i++){ 18 if(zz[i]=='1') 19 dp[i]=dp[i-1]+1; 20 else 21 dp[i]=dp[i-1]; 22 } 23 int len=zz.length(); 24 int pos=0; 25 for(int i=k;i<len;i++){ 26 if(zz[pos]=='0'&&zz[i]=='1') 27 dp[i]=dp[i-1]+1; 28 else if(zz[pos]==zz[i]) 29 dp[i]=dp[i-1]; 30 else 31 dp[i]=dp[i-1]-1; 32 pos++; 33 } 34 } 35 struct node 36 { 37 int left,right,min,max; 38 }c[1000010*4]; 39 void buildtree(int l,int r,int root) 40 { 41 c[root].left=l; 42 c[root].right=r; 43 if(l==r) 44 { 45 c[root].min=c[root].max=a[l]; 46 return ; 47 } 48 int mid=(l+r)/2; 49 buildtree(l,mid,root*2); 50 buildtree(mid+1,r,root*2+1); 51 c[root].min=min(c[root*2].min,c[root*2+1].min); 52 c[root].max=max(c[root*2].max,c[root*2+1].max); 53 } 54 void findtree(int l,int r,int root,int &min1,int &max1) 55 { 56 if(c[root].left==l&&c[root].right==r) 57 { 58 min1=c[root].min; 59 max1=c[root].max; 60 return ; 61 } 62 int mid=(c[root].left+c[root].right)/2; 63 if(mid<l) 64 findtree(l,r,root*2+1,min1,max1); 65 else if(mid>=r) 66 findtree(l,r,root*2,min1,max1); 67 else 68 { 69 int min2,max2; 70 findtree(l,mid,root*2,min1,max1); 71 findtree(mid+1,r,root*2+1,min2,max2); 72 min1=min(min1,min2); 73 max1=max(max1,max2); 74 } 75 } 76 int main() 77 { 78 scanf("%d%d%d",&n,&k,&p); 79 for(int i=1;i<=n;i++){ 80 int x; 81 scanf("%d",&x); 82 t+=(x+'0'); 83 } 84 int len=t.length(); 85 string s=t+t; 86 memset(dp,0,sizeof(dp)); 87 init(s); 88 for(int i=2*len-1;i>=0;i--){ 89 a[2*len-i]=dp[i]; 90 } 91 buildtree(1,2*len,1); 92 char r[maxn]; 93 scanf("%s",r); 94 int min1,max1; 95 int cnt=1; 96 for(int i=0;i<p;i++){ 97 if(r[i]=='!'){ 98 cnt=(cnt+1)%len; 99 } 100 else{ 101 if(k>=n){ 102 printf("%d\n",dp[2*len-1]); 103 continue; 104 } 105 if(!cnt) 106 findtree(cnt+1,cnt+n-k+1,1,min1,max1); 107 else 108 findtree(cnt,cnt+n-k,1,min1,max1); 109 printf("%d\n",max1); 110 } 111 } 112 return 0; 113 }
分析:直接暴力会T,用map来统计mp[a1]表示a1能有多少个组合,然后把相同的情况合并一下递推即可
1 #include "iostream" 2 #include "cstdio" 3 #include "cstring" 4 #include "string" 5 #include "cmath" 6 #include "map" 7 using namespace std; 8 map<long long,long long>mp; 9 map<long long,long long>::reverse_iterator it; 10 int main() 11 { 12 int n; 13 long long k; 14 cin>>n>>k; 15 for(int i=1;i<=n;i++){ 16 long long p; 17 cin>>p; 18 if(p>k) continue; 19 long long h=k/p; 20 for(it=mp.rbegin();it!=mp.rend();it++){ 21 long long m=it->first; 22 if(h>=m){ 23 mp[p*m]=mp[p*m]+it->second; 24 } 25 } 26 mp[p]=mp[p]+1; 27 } 28 long long ans=0; 29 for(it=mp.rbegin();it!=mp.rend();it++) 30 ans+=it->second; 31 cout<<ans<<endl; 32 }