20170711考试总结

来源:互联网 发布:python重定向到文件 编辑:程序博客网 时间:2024/06/11 04:50

隔膜

【问题描述】

steam 夏季大促销来啦,azui 大爷最近在 steam 上买了 1mol 的游

戏。一天他突然发现了一个搬砖的游戏:种砖头,每种砖头有 mi 个,每一个的价值为 di。每一个单位时间你必须搬一块砖,到无砖可搬为止。有一个得分系数 F,初始时 1。搬一块砖的得分为当时的得分系数 F*di。有个时间分割点。每过一个时间分割点,F 会自己加一。例如在时间 pi 的得分为 i*di,而在时间 pi+1 的得分为(i+1)*di。azui 大爷觉得这个游戏 too simple,不想去玩,于是让你去帮他上分,希望你能告诉他每局游戏的最大的分。你一定知道这么简单的题目怎么做,快帮帮 azui 大爷吧。

【输入格式】

第一行一个数 N。接下来的行,每行两个数,表示 mi  di之后的一行一个数 T。接下来的一行个数,pi

【样例输入 1】

2

3 8

5 10

1

20

【样例输出 1】

74

【样例输入 2】

1

1 1000

1

1

【样例输出 2】

1000 

【数据范围】

对于 30%的数据,

1<=N<=10

对于 100%的数据,

1<=N<=100

1<=mi<=109

0<=di<=1000

1<=t<=1001<=p2<p3<…<pt<=1012

题解:按d排序。

成绩:AC

分析:水题。

#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<cmath>using namespace std;const int N=100+10;struct node{long long num,val;bool operator < (const node &x)const{return val<x.val;}}arr[N];int n,T,now=1;long long p,f,ans,res;int main(){scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%lld %lld",&arr[i].num,&arr[i].val);sort(arr+1,arr+n+1);scanf("%d",&T);while(T--){scanf("%lld",&p);f++;for(;now<=n;now++){res+=arr[now].num;ans+=arr[now].num*arr[now].val*f;if(res>=p) break ;}if(res>p){arr[now].num=res-p;res=p;ans-=arr[now].num*arr[now].val*f;}elsenow++;}for(;now<=n;now++)ans+=arr[now].num*arr[now].val*(f+1);printf("%lld\n",ans);}


快递配对

【问题描述】

azui  大爷厌倦了每天在家颓废的生活,于是开始打工送快递。Jeremy 同学不想让 azui 大爷太轻松,于是想让他送快递的路程尽可能的长。一句话来说就是:给出一棵个点的树,将这个点两两配对,求所有可行的方案中配对两点间的距离的总和最大为多少。

【输入格式】

一个数 n(1<=n<=100,000,n 保证为偶数)接下来 n-1 行每行三个数 x,y,z 表示有一条长度为的边连接y(0<=z<=1,000,000,000)

【输出格式】

一个数表示答案。

【样例输入】

6

1 2 1

1 3 1

1 4 1

3 5 1

4 6 1


题解:找树的重心,让每一条路都经过树的重心。因为假设树的根是确定的,最佳方案一定是每个节点都越过根去找配对节点,因为要让每个节点越过根,去掉根后子树一定要尽量平均,即树的重心。

成绩:0

分析:文件输入输出没有打.in和.out(被自己zz掉/(ㄒoㄒ)/~~),考试时想到了平均,但树的重心的概念完全忘了( ˇˍˇ ),就乱搞了一个点作根。

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<stack>#include<algorithm>#include<vector>using namespace std;const int N=100000+10;const int inf=0x3f3f3f3f;void getint(int&son){    char c;int flag=1;son=0;    while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;    while(c>='0'&&c<='9'){son=son*10+c-48;c=getchar();}    son*=flag;}struct bian{    int v,w,next;}arr[N<<1];int n,a,b,cnt,s,t,Min=inf,fir[N],dp[N],son[N];long long w,dis[N],ans;bool vis[N];void link(int a,int b,int w){    arr[++cnt].v=a,arr[cnt].w=w;arr[cnt].next=fir[b],fir[b]=cnt;}void work(int x,int pre){son[x]=1;for(int i=fir[x];i;i=arr[i].next)if(arr[i].v!=pre)work(arr[i].v,x),son[x]+=son[arr[i].v];}void dfs(int x,int pre){for(int i=fir[x];i;i=arr[i].next)if(arr[i].v!=pre)dfs(arr[i].v,x),dp[x]=max(dp[x],son[arr[i].v]);dp[x]=max(dp[x],n-son[x]);}void Dfs(int x){vis[x]=1;for(int i=fir[x];i;i=arr[i].next)if(!vis[arr[i].v]){dis[arr[i].v]=dis[x]+arr[i].w;Dfs(arr[i].v);}}int main(){//freopen("pairing.in","r",stdin);//freopen("pairing.out","w",stdout);    getint(n);    for(int i=1;i<n;i++){scanf("%d %d %lld",&s,&t,&w);link(s,t,w),link(t,s,w);}work(1,-1),dfs(1,-1);for(int i=1;i<=n;i++)Min=min(Min,dp[i]);    for(int i=1;i<=n;i++)        if(dp[i]==Min){Dfs(i);break ;}for(int i=1;i<=n;i++)ans+=dis[i];printf("%lld\n",ans);}


【问题描述】

azui大爷在quack大爷的带领下开始玩集合了,可是他太懒了,不想做quack大爷布置的作业题,便拿来给你做了:

S 集合中有n个不同的元素,我们从1-n标号。考虑S 的子集Si,j,将这些子集排成一个r行c列矩阵的样子。

其中第一行为S1,1,S1,2,…,S1,c,第二行为S2,1,S2,2,..,S2,c一直到第r行为Sr,1, Sr,2,…, Sr,c。

这些集合还满足对于在一行中左右相邻的两个集右,左侧是右侧

的子集,即Si,j∈Si,j+1。

这些集合还满足对于在一列中上下相邻的两个集合,上方是下方

的子集,即Si,j∈Si+1,j。

问对于S 的全部子集,有多少可能的情况排成上述的矩阵(每个子集可以重复使用),结果模109 +7 输出。

你一定知道这么简单的题目怎么做,快帮帮azui大爷吧。

【输入格式】

一行三个数n,r,c.

【输出格式】

      一个数表示答案。

【样例输入】

1 2 2

【样例输出】

6

【样例解释】

1

2

3

4

如上图标号后,有:1是2和3的子集,1,2,3都是4的子集。

用0表示空集,1表示元素1,从左到右是1、2、3、4的话,有以下6种情况

0000 0001 0011 0101 0111 1111

 

【数据范围】

对于10%的数据,r*c*n <= 16

对于20%的数据,r*c <= 16, n <= 100

对于另20%的数据,r=1, c<=1000000

对于另10%的数据,n=1

对于100%的数据,r, c <= 1000000, n <= 10^9s

题解:把集合中每个数分开考虑,最后再把n=1时的答案n次方(简直不敢相信考场上就差这一步,然而n=1只有一个点%>_<%),考虑只填0和x,那x一定在矩阵的右下部分,就可以吧问题转换为从左上到右下一共有多少种走法(一共走r+c步,c步向下 => C(n,m) )。

成绩:0

分析:这次的文件输入输出不光没有打in和out还顺手注释掉了。。。但改过来也只有n=1的10分,主要是思考时看到特殊数据一直在人为地强化它的特殊性,半暴力半玄学地把式子写出来后n一变就懵掉(时间不够又很慌qnq)。

#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<cmath>#include<vector>using namespace std;const int N=100+10;const long long mod=1e9+7LL;int n,r,c,ans,map[N][N];int Max(int a,int b,int c){return max(a,max(b,c));}void dfs(int x,int y){int pos=c*(x-1)+y;if(pos>=r*c+1){ans++;return ;}for(int i=Max(1,map[x-1][y],map[x][y-1]);i<=n;i++){map[x][y]=i;if(y<c)dfs(x,y+1);elsedfs(x+1,1);}}void gcd(long long a,long long b,long long &x,long long &y){if(!b)x=1,y=0;elsegcd(b,a%b,y,x),y-=a/b*x;}int inv(int n) {    if(n == 1) return 1;    return (long long)(mod-mod/n)*inv(mod%n)%mod;}long long cal(long long n,long long m){if(m>n-m)m=n-m;long long res=1,x;for(int i=1;i<=m;i++){res=(res*(n-i+1))%mod;x=inv(i);while(x<0)x+=mod;res=(res*x)%mod;}return res;}long long qpow(long long tmp,int p){long long res=1LL;while(p){if(p&1)res=(res*tmp)%mod;p>>=1,tmp=(tmp*tmp)%mod;}return res;}int main(){scanf("%d %d %d",&n,&r,&c);printf("%lld\n",qpow(cal(r+c,c),n));return 0;}/*1 2 2*/


总结:感觉开发了自己的潜能。。(一场考试第一次两次文件错误O__O"…),我记得交卷前检查了的( ⊙ o ⊙ ),然而没看出来,错了之后又看了一遍,还是没看出来%>_<%。很多以前学过的东西忘了(树的重心o(╯□╰)o)各种失误也挺多的。。/(ㄒoㄒ)/~~,(果然洛谷说我今天大凶还忌参加模拟赛TAT)衷心期待明天不要炸得这么难看o@_@o 2333333333333333333333333333333333333333333333333333333333

原创粉丝点击