20:05:51 青春是挽不回的水,转眼消失在指尖。用力的浪费,再用力的后悔。——五月天《疯狂的世界》
第一题 谁拿了最多的奖学金
http://219.153.61.2:9000/contest/238/problem/1070
这道题重在打代码,适合用结构体,变量较多
#include<bits/stdc++.h> using namespace std; struct as{ char st[20]; int c; int j; char a; char b; int d; int jxj=0; }ss[1003]; int main() { int n,p,q,sum=0; cin>>n; for(int i=1;i<=n;i++) { cin>>ss[i].st; cin>>ss[i].c; cin>>ss[i].j; cin>>ss[i].a; cin>>ss[i].b; cin>>ss[i].d; if(ss[i].d>=1&&ss[i].c>80)ss[i].jxj+=8000; if(ss[i].c>85&&ss[i].j>80)ss[i].jxj+=4000; if(ss[i].c>90)ss[i].jxj+=2000; if(ss[i].c>85&&ss[i].b==‘Y‘) ss[i].jxj+=1000; if(ss[i].j>80&&ss[i].a==‘Y‘) ss[i].jxj+=850; } p=ss[1].jxj; for(int i=1;i<=n;i++) { if(ss[i].jxj>p) { p=ss[i].jxj; q=i; } sum+=ss[i].jxj; } cout<<ss[q].st<<endl<<p<<endl<<sum; return 0; }
像这种简单的题一定要仔细仔细再仔细!!!
21:41:23 如果 另个时空 另个身体 能不能 换另一种 结局 想见你 只想见你 未来过去 我只想见你 ——《想见你想见你想见你》
第二题 过河
http://219.153.61.2:9000/problem/1069
这道题是一道dp,但是如果只用简单的dp,就只能得到L<1000的那30分。首先,c++的空间复杂度是不支持数组开10^9这个大小的,其次,for循环后面的长度,时间复杂度也会超出范围,所以,这道题需要做一个优化。就是路径很长,但是石子数是很少的,而且青蛙最优走法是不走到石子的地方,所以只需要在路径的时候不断mod一次,就可以是程序大大优化。数组也没有必要开到10^9。
状态转移方程:f[i]=min(f[i],f[i-k]+vis[i]);
#include<bits/stdc++.h> using namespace std; int s,t,l,m,a[1000009],f[100009]; bool vis[100001]; int main() { scanf("%d%d%d%d",&l,&s,&t,&m); for(int i=1;i<=m;i++) cin>>a[i]; memset(f,60,sizeof(f)); f[0]=0; int o=0; sort(a,a+m+2); for(int i=1;i<=m+1;i++) { if(a[i]-a[i-1]<=t*s) o+=a[i]-a[i-1]; else o+=(a[i]-a[i-1])%t+t; vis[o]=true; } for(long long i=1;i<=o+t;i++) { for(int k=s;k<=t;k++) { if(i-k>=0) f[i]=min(f[i],f[i-k]+vis[i]); } } int ans=999999; for(int i=o;i<=o+t;i++) ans=min(ans,f[i]); printf("%d",ans); return 0; }
22:20:30 背影是真的人是假的 没什么执着 一百年前你不是你我不是我 ——《百年孤寂》
第三题 篝火晚会【O(n)】
http://219.153.61.2:9000/problem/1068
这里并没有指这m个点必须是在一块的,只是说从原序列里找出了m个点进行交换,交换代价为m。这一点很坑,会想很久。
贪心:假设能够构成环,那么置换的代价一定可以等于所有不在位置上的数的个数。它原先一定不在自己的位置,因为一个位置的点只能有1个,而它已被某个点取到了。将初始序列的状态固定,枚举置换得到的序列,每次找一遍即可。
发现许多数都不会在位置上,这些状态都浪费了。于是对于置换得到的数列,找每个数距离初始状态的长,统计相同长的个数即可进行优化。
#include<bits/stdc++.h> using namespace std; const int N=50001; int a[N],b[N]; int s[N],x[N],y[N],ans; int i,j,n; int main() { scanf("%d",&n); for(i=1; i<=n; i++) scanf("%d%d",&a[i],&b[i]); s[1]=1,s[n]=a[1]; s[2]=b[1]; for(i=3;i<n;i++) if(a[s[i-1]]==s[i-2]) s[i]=b[s[i-1]]; else s[i]=a[s[i-1]]; for(i=1;i<=n;i++) { int t1=i+1,t2=i-1; if(t1>n) t1=1; if(t2<1) t2=n; if((s[t1]!=a[s[i]]||s[t2]!=b[s[i]])&&(s[t2]!=a[s[i]]||s[t1]!=b[s[i]])) { printf("-1"); return 0; } } for(i=1;i<=n;i++) { x[(s[i]-i+n)%n]++; y[(s[i]+i-1)%n]++; } for(i=0;i<n;i++) { if (ans<x[i]) ans=x[i]; if (ans<y[i]) ans=y[i]; } printf("%d",n-ans); return 0; }
23:07:51 世上无可代替是与你相拥的感受 人海里万中无一粒属于我的温柔 ——《一粒》
第四题 等价表达式
http://219.153.61.2:9000/contest/238/problem/1067
要对一个表达式求值,首先要干掉表达式外面包着的多余的括号。若表达式内不含任何符号,只有数字(或者是一个a),那么我们直接返回数字(或者a^1)。否则,找到优先级最低的且不被括号包着的运算符。找最右边一个(因为我们的运算符都是左结合的)。
很容易想到暴力拆括号。但是,这个方法有2个麻烦的地方
1.需要实现一个储存因式的结构体并支持多种操作
2.(a-1)^10^10^10^10
等表达式会让结构体储存的东西多到爆炸。
一般这种表达式等问题通常都会通过用栈来解决
#include<bits/stdc++.h> #define ll long long #define oo 10020123 #define mod 100000007 using namespace std; ll xz(ll x,ll t){ ll ans=1; for(int i=1;i<=t;i++) ans=ans*x%mod; return ans; } ll sby(char *s,int l,int r,ll a) { int o=0,mm=52,mn=+oo,cnt=0,p[52],num=0; memset(p,0x3f,sizeof(p)); for(int i=r;i>=l;i--) { if(s[i]==‘)‘)o+=100; if(s[i]==‘(‘)o-=100; if(s[i]==‘^‘)p[i]=o+3,cnt++; if(s[i]==‘*‘)p[i]=o+2,cnt++; if(s[i]==‘+‘)p[i]=o+1,cnt++; if(s[i]==‘-‘)p[i]=o+1,cnt++; if(mn>p[i])mn=p[i],mm=i; } if(cnt==0) { for(int i=l;i<=r;i++)if(s[i]==‘a‘)return a; for(int i=l;i<=r;i++)if(isdigit(s[i]))num=num*10+s[i]-‘0‘; return num; } else { if(s[mm]==‘^‘)return xz(sby(s,l,mm-1,a),sby(s,mm+1,r,a)); if(s[mm]==‘*‘)return (sby(s,l,mm-1,a)*sby(s,mm+1,r,a))%mod; if(s[mm]==‘+‘)return (sby(s,l,mm-1,a)+sby(s,mm+1,r,a))%mod; if(s[mm]==‘-‘)return (sby(s,l,mm-1,a)-sby(s,mm+1,r,a))%mod; } return 0; } int main() { int l[27],n,ans[15]; char ss[27][52]; scanf("%[^\r]",ss[0]),getchar(); l[0]=strlen(ss[0]); cin>>n,getchar(); for(int i=1;i<=n;i++) { scanf("%[^\r]",ss[i]),getchar(); l[i]=strlen(ss[i]); } for(int i=0;i<=10;i++) ans[i]=sby(ss[0],0,l[0]-1,i-5); for(int i=1;i<=n;i++) { int f=1; for(int j=0;j<=10;j++) if(ans[j]!=sby(ss[i],0,l[i]-1,j-5)) { f=0; break; } if(f) printf("%c",‘A‘+i-1); } return 0; }
好啦!!!大功告成!!!
23:53:31 是你带我找到另一个天堂 远比想象中更美 我们怀抱里的这一个天堂 每一个梦想 有无限的快乐 ——《另一个天堂》
原文:https://www.cnblogs.com/wybxz/p/12203803.html