第一次写博客,有点小小的激动QAQ。表决心,谈理想之类的话就很少说了,反正平时说的也够多了。上大学以后才了解到算法竞赛究竟是个什么东西。高一的时候一位清华的教授还来过咱们学校普及了信息学奥赛,当时讲了一道例题,上了大学以后才知道,原来,,那是汉诺塔。有点遗憾,在江苏这样一个试卷难考生多招生名额少的地方,信息学竞赛普及度真的很低。有时候会想,若是我可以有条件在初中甚至小学就接触编程,如今的我会不会不同。node
上大学以后的我真的变了一我的了吧,或许是高考的失利带给个人感触与变化。很多人理解不了,上大学以后的我为何拼命地学,由于他们不懂,在这里,我终于能够不用像之前同样,全部的努力,全部的能力只被最后的一场考试定义。一位超级优秀的学妹曾经问过我,“学长,你有明确的目标么”。当时,我哑口无言,才发现原来我只知道埋头,殊不知道本身要去哪。如今,我终于明白,也终于找到了。python
进入南理工的第一天起,我发誓我要在这里作到最好,到目前为止,有不少事情本身作的很不错,但也有很多事情,本身能清楚感觉到差距的存在,就好比眼前的算法竞赛。的确很多比我厉害的人是由于大学之前的基础,但仍然有许许多多像我同样从零开始的人啊。全部的不成功,都应该首先从自身努力程度上找缘由吧。记住,你要在这里作到最好,那就必须让你的努力配得上你所指望的成就。ios
-----------------------------------------------------------------------手动分割线,进入正题…………^.^c++
前天忽然高烧,养了两天病。原来在宿舍里偷偷待一天这么爽(仅此一次,下不为例)。程序员
错过了昨晚的div3,今天下午汇编课上机的时间就用来写了写(天天这么多人找我DEBUG挺烦的其实。)。花了一个小时左右,过了四道题,印象中尚未比这更快过,大概是由于,此次前几题简单??粗略估计了一下罚时,若是放在昨晚的话,大概能够排到800名,错过了一次绝佳的上分机会(惋惜没若是~-~)。算法
A题编程
C++数组
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define scan(i) scanf("%d",&i) 4 int a[10]; 5 int main(){ 6 for(int i=1;i<=4;i++){ 7 scan(a[i]); 8 } 9 sort(a+1,a+5); 10 for(int i=1;i<=3;i++){ 11 int x=a[4]-a[i]; 12 printf("%d ",x); 13 } 14 return 0; 15 }
我仍是个病人,先睡觉了。明天再来哈。函数
Python测试
1 a, b, c, d = sorted(map(int, input().split())) 2 print(d-a, d-b, d-c)
只要两行,有点气人唉
B题
这道题也很简单,只要细心一点把全部状况考虑全就能够了。对于一组数,能够对每个数进行三种操做,加一个D,减一个D,或者不变。注意,对于这一组数,正数D的值是固定的。那么首先须要考虑的是这一组数是由多少个不一样的值组成,能够用一下unique函数,(!!!用以前必定要先排序!!上次由于这个问题卡了很久)。若是组成这一组数的值超过三个,那么必定不存在D知足条件。若是正好是三个,则判断是否成等差数列。
而对于一个或两个的状况,D必定存在,此时须要找一个最小的D。若是是一个,那么D显然是0。而,若是是两个的话,则要分状况,若是两数之差为偶数,则输出差的一半。而若是两数之差为奇数,则只能将其中一个变为另一个,输出两数之差。
C++
1 #include <bits/stdc++.h> 2 using namespace std; 3 int a[105]; 4 #define scan(i) scanf("%d",&i) 5 int main(){ 6 int n;scan(n); 7 for(int i=1;i<=n;i++)scan(a[i]); 8 sort(a+1,a+n+1); 9 int x=unique(a+1,a+n+1)-(a+1); 10 if(x>=4)cout<<-1; 11 else if(x==3){ 12 if((a[2]-a[1])==(a[3]-a[2]))cout<<(a[2]-a[1]); 13 else cout<<-1; 14 } 15 else if(x==2){ 16 if((a[2]+a[1])%2==0)cout<<(a[2]+a[1])/2-a[1]; 17 else cout<<(a[2]-a[1]); 18 } 19 else cout<<0; 20 return 0; 21 }
Python
1 input() 2 a = list(set(list(map(int, input().split())))) 3 a = sorted(a) 4 if len(a) == 1:print(0) 5 elif len(a) == 2: 6 x = a[1]-a[0] 7 if x % 2 == 0: 8 x = x/2 9 print(int(x)) 10 else:print(x) 11 elif len(a)==3: 12 x = a[1] - a[0] 13 if a[2] - a[1] == x: 14 print(x) 15 else:print(-1) 16 else:print(-1)
python只要先把列表转换为集合,再把集合转换为列表,一条语句就很方便的完成了去重的过程。不过python真心慢啊,时长用了c++的四倍。
C题
没错,又是一道模拟题,我这种菜鸡也就只能写写这种模拟题了。首先算一下全部食物至多可以坚持多少个星期,而后再对从周一到周日出发七种状况进行模拟,得出最长天数就行了
1 #include <bits/stdc++.h> 2 using namespace std; 3 int a,b,c; 4 char w[8]={'.','a','b','c','a','c','b','a'}; 5 int getday(int d){ #d为1到7,分别表示周一到周日 6 int a1=a,b1=b,c1=c; #存储去除整周以后剩余的食物 7 int cnt=0; 8 while(1){ 9 if(w[d]=='a'){ 10 if(a1==0)break; 11 else{ 12 a1--;cnt++; 13 } 14 } 15 else if(w[d]=='b'){ 16 if(b1==0)break; 17 else{ 18 b1--;cnt++; 19 } 20 } 21 else{ 22 if(c1==0)break; 23 else{ 24 c1--;cnt++; 25 } 26 } 27 if(d==7)d=1; #表示已经到周日了,下一天应该是周一 28 else d++; 29 } 30 return cnt; 31 } 32 int main(){ 33 scanf("%d%d%d",&a,&b,&c); 34 int i1=a/3,i2=b/2,i3=c/2; 35 int i=min(i1,i2);i=min(i,i3); 36 long long day=7*i; 37 a-=3*i;b-=2*i;c-=2*i; 38 int ma=0; 39 for(int i=1;i<=7;i++){ 40 if(getday(i)>ma)ma=getday(i); 41 } 42 day+=ma; 43 printf("%lld",day); 44 return 0; 45 }
老师说一个厉害的程序员,main函数应该是至关整洁的。像这种对不一样状况模拟取最优值的状况,尽可能的用函数去写吧。
D题
这道题是一条普通的的贪心。只要想清楚一个问题就行了,在有阳光照射的地方,若是用电池,电池减一但收集器加一,也就是没有损耗,但若是用收集器,总能量就减一,为了尽可能跑的远,就须要尽量的在有阳光的地方用电池,这样一来,在没有阳光的地方,就须要尽量的不用电池。注意,收集器有最大容量。
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn=2e5+5; 4 int m[maxn]; 5 int n,b,a; 6 int flag=1; 7 #define scan(i) scanf("%d",&i) 8 int main(){ 9 scan(n);scan(b);scan(a); 10 for(int i=1;i<=n;i++)scan(m[i]); 11 int i;int a1=a; 12 for(i=1;i<=n;i++){ 13 if(a1==0&&b==0){ 14 flag=0; 15 cout<<(i-1);break; 16 } 17 if(m[i]==1){ 18 if(b&&a1<a){ 19 b--;a1++; 20 } 21 else{ 22 a1--; 23 } 24 } 25 else{ 26 if(a1)a1--; 27 else b--; 28 } 29 if(a1==0&&b==0){ 30 flag=0; 31 cout<<i;break; 32 } 33 } 34 if(flag)cout<<n; #wa了一次,就是由于没有这条语句。忘记了走彻底部路程以后的输出。 35 return 0; 36 }
看到这题,想起来上学期期末那段时间写的一道dp,也是一个路程中能量补给的问题。(话说那段时间是真轻松,整个一月几乎没课,期末考又没压力,偷偷带了电脑写代码^-^)
Time Limit: 1000/1000 MS (Java/Others)
Memory Limit: 32768/32768 K (Java/Others)
这道题,当时想了很久。这是我第一次知道动态规划这个东西。本身写的时候,就当作贪心来处理,果不其然的wa了,还满觉得本身想的没错,我在每走一步以前都选择的是到下一步时间最短的方法,
最后的总时长理应也是最短的呀。好吧,当时的想法真愚蠢。贪心算法大概,就是“鼠目寸光”吧,只想着眼前的利益,却忘了要获得的是什么,而用动态规划的话,大概就是“指挥若定,决胜千里”的感受
吧,只要保证最后结果最优化。中间的某一些点之间或许没有贪心获得的效果好,但这一点小牺牲是为了换取更大的利益。运筹学真的是一门很深的学问,有机会必定要好好钻研。
状态转移方程很简单 dp[i]=min(dp[i],dp[j]+time) j<i 其他的一些附加条件计算稍微繁琐一点,当心写就行了。
1 #include <iostream> 2 using namespace std; 3 int path[102]; 4 double dp[102]; 5 int main() { 6 int L, N, C, T, vr, vt1, vt2; 7 while (cin >> L) { 8 cin >> N >> C >> T; 9 cin >> vr >> vt1 >> vt2; 10 for (int i = 1; i <= N; ++i) 11 cin >> path[i]; 12 path[0] = 0; path[N + 1] = L; 13 dp[0] = 0; 14 for(int i=1;i<=N+1;i++){ 15 double min=1000000; 16 for(int j=0;j<i;++j){ 17 double temp; 18 if(path[i]-path[j]>=C) 19 temp = dp[j] + C * 1.0 / vt1 + (path[i] - path[j] - C)*1.0 / vt2; 20 else 21 temp=dp[j]+(path[i]-path[j])*1.0/vt1; 22 if(j>0) 23 temp+=T; 24 if(temp<min) 25 min=temp; 26 } 27 dp[i] = min; 28 } 29 double rt; 30 rt = L * 1.0 / vr; 31 if(dp[N+1]<rt) 32 cout<<"What a pity rabbit!"<<endl; 33 else 34 cout<<"Good job,rabbit!"<<endl; 35 } 36 return 0; 37 }
E题
仍是模拟。。。。。终于用了一回上学期学过的手写链表,虽然会有一点麻烦,皮一下依然很开心。这题主要要说的,就是如何快速,找到当前状况下存在的最大值,和最大值对应的下标。
用一个check数组保存每个值的状态,这样在寻找最大值的时候,能够从n开始,若是这个值已经被用过了,就减一再判断,直到找到当前未用的最大值。而后用position数组保存每个值的下标,方便索引。
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn=2e5+5; 4 int n,k,x; 5 struct node{ 6 int val; 7 int id; 8 node *pre; 9 node *next; 10 }; 11 node p[maxn]; 12 int ans[maxn]; 13 int position[maxn]; 14 bool check[maxn]; 15 inline void build(){ 16 for(int i=1;i<=n;i++){ 17 scanf("%d",&x); 18 p[i].val=x; 19 p[i].id=i; 20 p[i].pre=&p[i-1];p[i].next=&p[i+1]; 21 if(i==1)p[i].pre=NULL; 22 if(i==n)p[i].next=NULL; 23 position[x]=i; 24 } 25 return; 26 } 27 int main(){ 28 scanf("%d%d",&n,&k); 29 build(); 30 int ma=n; 31 int an=1; 32 while(ma!=0){ 33 check[ma]=true; 34 ans[position[ma]]=an; 35 int po=position[ma]; 36 int k1=k;int k2=k; 37 int p1=po,p2=po; 38 while(k1--){ 39 if(p[po].next==NULL)break; 40 int v=p[po].next->val; 41 check[v]=true; 42 ans[position[v]]=an; 43 p1=p[po].next->id; 44 p[po].next=p[po].next->next; 45 } 46 while(k2--){ 47 if(p[po].pre==NULL)break; 48 int v=p[po].pre->val; 49 check[v]=true; 50 ans[position[v]]=an; 51 p2=p[po].pre->id; 52 p[po].pre=p[po].pre->pre; 53 } 54 if(p[p1].next!=NULL)p1=p[p1].next->id; 55 else p1=n+1; 56 if(p[p2].pre!=NULL)p2=p[p2].pre->id; 57 else p2=0; 58 if(p1<=n&&p2>=1){ 59 p[p1].pre=&p[p2]; 60 p[p2].next=&p[p1]; 61 } 62 if(p1<=n&&p2<1)p[p1].pre=NULL; 63 if(p1>n&&p2>=1)p[p2].next=NULL; 64 if(an==1)an=2;else an=1; 65 while(check[ma])ma--; 66 } 67 for(int i=1;i<=n;i++) 68 printf("%d",ans[i]); 69 return 0; 70 }
未完待续。。。。。。