Test 2019.5.4
今天下午日常考试,交上去的时候以为稳稳300(满分),一评测190,真香。好吧,那来总结下本次考试。
题面
和为给定数 (sum.cpp) 题目传送门: 链接
插队(que.cpp) 题目传送门: 链接
方格取数(弱化版) 题目传送门:链接 注:现在只要求求一条路径的最大和。
题解
sum
比较简单,用二分查找就可以了,提交,90分。 (啪~啪)
后来发现是数组开的不够大,加大了一些就过了
#include<bits/stdc++.h> using namespace std; int n,m,s[100009],i; //注意这里要开大一点 int ans[1005][3],p; bool b=true; int rain(int x){ //二分模板 int l=1,r=n,mid; while(l<=r) { mid=l+((r-l)>>1); if(s[mid]==x)return mid; if(s[mid]<x)l=mid+1; if(s[mid]>x)r=mid-1; } return 0; } int main(){ scanf("%d",&n); for(i=1;i<=n;i++)scanf("%d",&s[i]); scanf("%d",&m); sort(s+1,s+n+1); for(i=1;s[i]<=m/2;i++) { if(rain(m-s[i]) && rain(m-s[i])!=i) { p++; ans[p][1]=s[i]; ans[p][2]=m-s[i]; b=false; } } int minn=9999999,minx; if(!b){ for(i=1;i<=p;i++){ if(ans[i][1]>ans[i][2])swap(ans[i][1],ans[i][2]); if(ans[i][1]<minn){ minn=ans[i][1]; minx=i; } } printf("%d %d",ans[minx][1],ans[minx][2]); } else if(b)printf("No"); return 0; }
que.cpp
这道题目交上去的时候以为是稳100的,可结果是0分啊!!!0分啊!!!
自己看了半天没看出问题来,后来看了半天实在没看懂只能屁颠屁颠跑去问老师,标程是张这样的(落差好大):
#include<cstdio> #define maxn 393939 using namespace std; int n, q, x, y; int f[maxn], g[maxn], head; int main(){ scanf("%d%d", &n, &q); for(int i = 1; i < n+1; i++)f[i] = i+1, g[i] = i-1; head = 1; while(q--){ scanf("%d%d", &x, &y); if(x==head)head = f[x]; f[g[x]] = f[x]; g[f[x]] = g[x]; f[x] = f[y]; g[f[y]] = x; f[y] = x; g[x] = y; } int i = head, j = 0; while(i!=n+1){ printf("%d ", i); i = f[i]; } return 0; }
这道题目的最最正解是双向链表,目前还没有学,等以后学了再来补上.....
box.cpp
标准的动态规划,比较简单。
每个点的最大值用递推公式得:max(sum[x-1][y],sum[x][y-1])+s[x][y]
那么这道题目的思路就清晰了:把每个点的最大值得出,然后输出就行了;
但据说原题不是张这样的,原题:链接
#include<bits/stdc++.h> #define l 15 using namespace std; int x,y,z; int n,s[l][l],sum[l][l]; int t,i,j; int rain(int x,int y){return max(sum[x-1][y],sum[x][y-1])+s[x][y];} int main(){ scanf("%d",&n); while(scanf("%d %d %d",&x,&y,&z)){ if(x==0 && y==0 && z==0)break; s[x][y] = z; } for(i=1;i<=n;i++) for(j=1;j<=n;j++) sum[i][j]=rain(i,j); printf("%d\n",sum[n][n]); return 0; }