关于军训的模拟赛-R2
终于我也参加了一场有R1 && R2的比赛呢。
因为种种原因,老师认为上次的考试没有体现我们的真实水平,于是举办了毒瘤R2,其实也不是非常毒瘤,还是一贯的风格。
T1 : profit
概括题意:带点权的“没有上司的舞会”。然而题意有一点歧义,得看样例才能懂。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 # include <cstdio> 2 # include <iostream> 3 4 using namespace std; 5 6 const int maxn=100009; 7 int n,firs[maxn],h,x,y,dep[maxn]; 8 int a[maxn]; 9 long long dp[maxn][2]; 10 struct edge 11 { 12 int too,nex; 13 }g[maxn<<1]; 14 15 void dfs (int x) 16 { 17 int j; 18 dp[x][0]=a[x]; 19 for (int i=firs[x];i;i=g[i].nex) 20 { 21 j=g[i].too; 22 if(dep[j]) continue; 23 dep[j]=dep[x]+1; 24 dfs(j); 25 dp[x][0]+=dp[j][1]; 26 dp[x][1]+=max(dp[j][1],dp[j][0]); 27 } 28 } 29 30 void add (int x,int y) 31 { 32 g[++h].too=y; 33 g[h].nex=firs[x]; 34 firs[x]=h; 35 } 36 37 int main() 38 { 39 freopen("profit.in","r",stdin); 40 freopen("profit.out","w",stdout); 41 42 scanf("%d",&n); 43 for (int i=1;i<=n;++i) 44 scanf("%d",&a[i]); 45 for (int i=1;i<n;++i) 46 { 47 scanf("%d%d",&x,&y); 48 add(x,y); 49 add(y,x); 50 } 51 dep[1]=1; 52 dfs(1); 53 printf("%lld",max(dp[1][0],dp[1][1])); 54 return 0; 55 }
T2 : Torch
任意给定一个正整数n(n<=100000),求一个最小的正整数m,使得n*m的十进制表示形式里只含有1和0。输入n如果有解输出m,无解则输出“No Solution”。
首先写一个暴力,然后打表找规律,现在来看一下我打了哪些表:对于1-10000的答案,1-10000的二进制分解,答案的二进制分解,乘积的二进制分解,乘积分解质因数....于是这五个表都没啥用呢...真的找不到任何规律。后来想了一个方法优化暴力,直接枚举那个乘积,因为乘积只由0,1组成,可以用二进制来枚举,这样可以少枚举很多无效的情况,但是怎么判断无解呢?并没有什么办法,但是如果..乘积..超过longlong了是不是就不大好做了...所以只枚举乘积没有爆longlong的一些情况,如果这些都不出解就干脆输出无解好了。虽然看起来非常不科学,但是竟然A了...
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 # include <cstdio> 2 # include <iostream> 3 4 using namespace std; 5 6 int n,m; 7 long long ans=0; 8 int t[100],len; 9 10 long long check (int x) 11 { 12 long long an=0; 13 len=0; 14 while (x) 15 { 16 t[++len]=x%2; 17 x/=2; 18 } 19 for (int i=len;i>=1;--i) 20 an=an*10+t[i]; 21 if(an<0) return -1; 22 if(an%n==0) return an/n; 23 return -1; 24 } 25 26 int main() 27 { 28 freopen("torch.in","r",stdin); 29 freopen("torch.out","w",stdout); 30 31 scanf("%d",&n); 32 for (int i=1;i<=1048600;++i) 33 { 34 ans=check(i); 35 if(ans!=-1) 36 { 37 cout<<ans; 38 fclose(stdin); 39 fclose(stdout); 40 return 0; 41 } 42 } 43 printf("No Solution"); 44 fclose(stdin); 45 fclose(stdout); 46 return 0; 47 }
T3 : LongestRegularBracketsSequence
真·神题,图片题面,极长文件名,反复检查了十多遍也不放心。
求括号匹配最长串,SDWC讲过的,但是当时的方法极其复杂,其实也有简单一点的做法。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 # include <cstdio> 2 # include <iostream> 3 # include <cstring> 4 # include <string> 5 6 using namespace std; 7 8 const int maxn=1000009; 9 string s; 10 int a[maxn],len,Top=0; 11 int sta[maxn],pos[maxn]; 12 13 int main() 14 { 15 freopen("LongestRegularBracketsSequence.in","r",stdin); 16 freopen("LongestRegularBracketsSequence.out","w",stdout); 17 cin>>s; 18 len=s.length(); 19 for (int i=0;i<len;++i) 20 { 21 if(s[i]=='(') sta[++Top]=1,pos[Top]=i; 22 else if(s[i]=='[') sta[++Top]=2,pos[Top]=i; 23 else 24 { 25 if(s[i]==')') 26 { 27 if(sta[Top]==1) 28 a[ pos[Top] ]=a[i]=1,Top--; 29 else Top=0; 30 } 31 else if(s[i]==']') 32 { 33 if(sta[Top]==2) 34 a[ pos[Top] ]=a[i]=1,Top--; 35 else Top=0; 36 } 37 } 38 } 39 int beg=0,ans=0,n=0,ans_len=0; 40 for (int i=0;i<len;++i) 41 { 42 if(a[i]) n++; 43 else 44 { 45 if(n>ans_len) ans_len=n,ans=beg; 46 beg=i+1; 47 n=0; 48 } 49 } 50 if(n>ans_len) ans_len=n,ans=beg; 51 for (int i=0;i<ans_len;++i) 52 printf("%c",s[i+ans]); 53 fclose(stdin); 54 fclose(stdout); 55 return 0; 56 }
T4 : MagicFingerprint
粘图片真开心。
看起来有点像数位dp,但是不是。其实就是一种逆向的推理,从7开始把一个数分裂成两个,但是我写炸了,最后就交了暴力。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 # include <cstdio> 2 # include <iostream> 3 4 using namespace std; 5 6 int a,b,ans; 7 int d[10],len; 8 9 bool check (int x) 10 { 11 len=0; 12 while (x) 13 { 14 d[++len]=x%10; 15 x/=10; 16 } 17 while (len!=1) 18 { 19 for (int i=1;i<len;++i) 20 d[i]=max(d[i],d[i+1])-min(d[i],d[i+1]); 21 len--; 22 } 23 if(d[1]==7) return true; 24 return false; 25 } 26 27 int main() 28 { 29 freopen("MagicFingerprint.in","r",stdin); 30 freopen("MagicFingerprint.out","w",stdout); 31 32 scanf("%d%d",&a,&b); 33 for (int i=a;i<=b;++i) 34 if(check(i)) ans++; 35 printf("%d",ans); 36 37 fclose(stdin); 38 fclose(stdout); 39 return 0; 40 }
---shzr