NOIP 模拟题 简单题 随便做 题解与总结
来源:互联网 发布:矩阵微分方程 编辑:程序博客网 时间:2024/05/21 06:19
简单题”题解
- T1 简
题解:
水题啊,排个序取奇数位的数就可以了。
代码:
#include<cstdio>#include<algorithm>using namespace std;typedef long long ll;const ll size = 100005;ll n,ans = 0;ll da[2*size];//数组大小啊!!!int main(){ scanf("%lld",&n); for (ll i = 1;i <= 2 * n;i++) scanf("%lld",&da[i]); sort(da + 1 , da + 1 + 2*n); for (ll i =1;i<=2*n;i+=2) ans += da[i]; printf("%lld",ans); return 0;}
- T2 单
题解:
不难啊,考虑到一条边的两端的点
代码(点不进去了,就用了标程):
#include<cstdio>#include<algorithm>#include<iostream>#include<cstring>using namespace std;typedef long long ll;const int N=100010;ll T,t,n,edgenum,head[N],c[N],fa[N],dep[N],atot,ans[N],v[N];struct edge { int v,next;} e[N<<1];struct node { ll tot,con;} tr[N];ll read() { ll x=0; char ch=getchar(); while(ch<'0'||ch>'9') ch=getchar(); while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x;}void addedge(int f,int t) { e[++edgenum].v=t; e[edgenum].next=head[f]; head[f]=edgenum;}void dfs1(int a,int pre) { fa[a]=pre; dep[a]=dep[pre]+1; for(int i=head[a]; i; i=e[i].next) { if(e[i].v==pre) continue; dfs1(e[i].v,a); }}inline void solve1() { ll root_tot=0,root_con=0,sum=0; dep[0]=-1; dfs1(1,0); for(int i=2; i<=n; i++) { tr[i].con=c[fa[i]]-c[i]; tr[i].tot=1; tr[fa[i]].tot--; tr[fa[i]].con-=tr[i].con; } for(int i=2; i<=n; i++) { root_tot+=tr[i].tot*dep[i]; root_con+=tr[i].con*dep[i]; } atot=(2*c[1]-root_con)/root_tot; for(int i=2; i<=n; i++) ans[i]=(tr[i].con+tr[i].tot*atot)/2,sum+=ans[i]; ans[1]=atot-sum;}void dfs2(int a,int pre) { fa[a]=pre; dep[a]=dep[pre]+1; for(int i=head[a]; i; i=e[i].next) { if(e[i].v==pre) continue; dfs2(e[i].v,a); v[a]+=v[e[i].v]; }}void dfs3(ll sum,int a,int pre) { ans[a]=(sum-(v[a]<<1))+ans[pre]; for(int i=head[a]; i; i=e[i].next) { if(e[i].v==pre) continue; dfs3(sum,e[i].v,a); }}inline void solve2() { ll sum=0; for(int i=1; i<=n; i++) v[i]=c[i],sum+=c[i]; dep[0]=-1; dfs2(1,0); for(int i=2; i<=n; i++) ans[1]+=c[i]*dep[i]; for(int i=head[1]; i; i=e[i].next) dfs3(sum,e[i].v,1);}int main() { int a,b; T=read(); while(T--) { edgenum=0; memset(ans,0,sizeof ans); memset(head,0,sizeof head); n=read(); for(int i=1; i<n; i++) { a=read(),b=read(); addedge(a,b),addedge(b,a); } t=read(); for(int i=1; i<=n; i++) c[i]=read(); if(t) solve1(); else solve2(); for(int i=1; i<=n; i++) printf("%lld ",ans[i]); putchar('\n'); } return 0;}
- T3 题
题解:
(见我另一篇博客:
http://blog.csdn.net/Demon_Rieman/article/details/78066943)
“随便做”题解
- T1 随
题解:
(好高级的做法) 明显我们要用
都不行,于是我们观察,发现每次都要用 来转移,并且每次转移方式都是一样的,那不就是???对啦,递归的,也就是说,实际上答案就是的次方(类似矩阵),然后就写一个伪.矩阵快速幂就可以了,这样空间,时间,可以过。(也有人写滚动数组,但我不熟啊,所以就写了一个不滚动的。但是滚动要快一倍……)
代码:
#include<cstdio>#include<cstring>using namespace std;typedef long long ll;const ll size = 1005;const ll MOD = 1000000007;ll n , m, mode;ll ans[size] , replace[size] ,t[size];ll q_pow(ll a,ll b,ll c){ ll res = 1; while (b) { if (b%2) (res*=a)%=c; b/=2; (a*=a)%=c; } res %= c; return res;}ll inv(ll a,ll b)//b 是质数 { return q_pow(a , b - 2 ,MOD);}void mat_mult(ll *a , ll b[]){ ll tmp[size];memset(tmp,0,sizeof tmp); for (ll i = 1;i < mode;i++) for (ll j = 1;j < mode;j++) ( tmp[ (i * j) % mode ] += a[i] * b[j] )%= MOD; for (ll i = 1;i < mode;i++) a[i] = tmp[i];}void mat_q_pow(ll *a,ll *b,ll m)//答案 mod c { a[1] = 1; while (m) { if (m%2==1) mat_mult(a,b); m/=2; mat_mult(b,b); }}int main(){ scanf("%lld%lld%lld",&n,&m,&mode); for (int i = 1;i<=n;i++) { ll x; scanf("%lld",&x); t[x]++; } ll invn = inv( n , MOD); for (int i = 1;i < mode;i++) replace[i] = (t[i] * invn)%MOD ; //for (int i = 0;i<mode;i++) //printf("%lld " , replace[i]); mat_q_pow(ans , replace , m ); ll tot = 0; for (ll i= 1;i < mode;i++) tot = (tot + i * ans[i])%MOD; (tot += MOD)%=MOD; printf("%lld",tot);}
- T2 便
题解:
限制条件推一推就变成了对于每一行,其增量相同,也就是对于同一行的
代码:
#include <bits/stdc++.h>typedef long long ll;const ll size =200201;using namespace std;int rank[size], twoo[size], mi[size], fa[size],_r, _c, n,T;struct ob { int ri, ci, rank; bool operator <(const ob &a) const { return ci < a.ci; }}obb[size];int findfa(int x) {if (fa[x] == x) return x;int rt = findfa(fa[x]); rank[x] += rank[fa[x]]; fa[x] = rt; return fa[x];}int unionm(int a,int b,int ci){ int faa = findfa(a),fab = findfa(b); if (rank[faa]>rank[fab]) fa[faa] = fab; if (rank[faa] == rank[fab]) rank[faa]++;}bool merge(int a, int b, int ci) { int ra = findfa(a), rb = findfa(b); if (ra != rb) { fa[ra] = rb;rank[ra] = ci - rank[a] + rank[b]; return 1; } else { bool yk= (rank[a] == rank[b] + ci); return yk; }}bool panding() { for(int i= 0;i<= n;i++) { fa[i] = i; rank[i] = 0; }sort(obb + 1, obb + 1 + n); for(int i= 1;i<= n - 1;i++) if(obb[i].ci == obb[i + 1].ci) if(!merge(obb[i].ri, obb[i + 1].ri, obb[i + 1].rank - obb[i].rank)) return false;memset(twoo, 0x3f, sizeof(twoo));memset(mi, 0x3f, sizeof(mi));for(int i= 1;i<= n;i++) { int rt = findfa(obb[i].ri); twoo[rt] = min(twoo[rt], obb[i].rank + rank[obb[i].ri]);} for(int i=0;i<=_r;i++) { int rt = findfa(i); mi[rt] = min(mi[rt], -rank[i]); } for(int i=0;i<= _r;i++) if (fa[i] == i && (twoo[i] + mi[i] < 0)) return 0; return 1;}int check = 1;int main(){ scanf("%d",&T);while(T--){ check = 1; scanf("%d%d%d",&_r,&_c,&n); for(int i=1;i<=n;i++) scanf("%d%d%d",&obb[i].ri,&obb[i].ci,&obb[i].rank); for(int i= 0;i<= n;i++) if (obb[i].rank < 0) check = 0; if (panding()&&check) printf( "Yes\n"); else printf("No\n"); } } return 0;}
- T3 做
(惊天好题,这么好的题目背景,肯定要截下来)
题解:
实际是水题,膜法师肯定不会动,所以他只会膜或者喊:“苟利国家生死以,竹外桃花三两枝。”恢复,而香港记者则每次使
代码:
#include<cstdio>#include<algorithm>#include<cstring>using namespace std;int T;int main(){ scanf("%d",&T); int a,b; scanf("%d%d",&a,&b); while (T--) { int x1,x2,y1,y2; int c ,d; scanf("%d%d%d%d%d%d" , &x1 , &y1 , &x2 , &y2 , &c , &d); int dx = abs(x1-x2) , dy = abs(y1-y2); int tot = 0; while (dx > 0 || dy > 0) { if (c < a) c+=b; else {tot += dx*dx + dy*dy; c -= a;} if (tot >= d) break; if (dx > dy) dx--;else dy--; if (dx > dy) dx--;else dy--; } if (tot>=d) printf("NAIVE\n"); else printf("SIMPLE\n"); } return 0;}
总结:
- day1
T1 数组开小了,气啊。下次一定要好好注意啊,考试时可不能犯这种错误。
T2 考试时没怎么想,连30的暴力都没写,主要是对树的题还是不是很熟。
T3 我推了好久啊,但也没推出正解,知识水平还不够啊,组合数学要多学学,虽然数学我最不好的就是组合数学,最后写暴力dp还得了80分,所以应该好好调整做题时间,想很久想不出来先把暴力写了,然后把题做完再来看这道题。(这题想了2个小时,但暴力5多分钟时候就想到了,然后就这样浪费了1小时50分钟,如果拿来做第二题,还能得30分)。
- day2
T1 做不来,就只写了一个20分的骗分,结果这都只骗到10分。 如果多想想还是有可能想出来的。然后改的时候居然模数搞错了,害的只有20,改了一下午才发现…….
T2 跟day1的T3一样,花了我大多时间,一开始想正解,没想出来(以前基本没用过带权并查集),然后写90分的暴力,就是强行记录差以及强行把矩阵做出来,但不知为何只有10,码力不足啊,一定是哪写错了。
T3 千古奇冤啊,我写平方时,居然写成了数学的,没想到样例还能过,然后这题又简单,就没去造数据了。这题告诉我再简单的题也要造点数据验证。
很重要的:考试时一定要注意数组大小,符号,模数。
- NOIP 模拟题 简单题 随便做 题解与总结
- NOIP模拟题题解
- 【20150904】NOIP模拟套题01 day1 题解 & 总结
- 【20150905】NOIP模拟套题01 day2 题解 & 总结
- 【20150911】NOIP模拟套题02 day1 题解 & 总结
- 【20150915】NOIP模拟套题02 day2 题解 & 总结
- NOIP 2015模拟赛[nodgd题]题解&总结
- NOIP 2016模拟赛[南开题]题解&总结
- 【NOIP模拟】20140809 题解 & 总结
- 【NOIP模拟】20140812 题解 & 总结
- 【NOIP模拟】20140813 题解 & 总结
- 【NOIP模拟】20140814 题解 & 总结
- 【NOIP模拟】20140815 题解 & 总结
- 【NOIP模拟】20140817 题解 & 总结
- 【NOIP模拟】20140907 题解 & 总结
- 【NOIP模拟】20140913 题解 & 总结
- 【20150912】NOIP模拟 题解 & 总结
- noip模拟题—跳跃版图 题解
- SpringMVC整合swagger
- 一些基础知识
- 一条简单的SQL的加锁实现分析
- Jmeter接口压力测试(先登录再测接口)
- java8笔记_1
- NOIP 模拟题 简单题 随便做 题解与总结
- iOS中关键字copy与mutableCopy的详解,看我你就都懂了
- Maven管理
- python读取LMDB中的图像
- python实现接口自动化测试框架
- MySQL之索引:索引字段使用顺序对复合索引有效性的影响
- string的皮毛与范围for----C++学习之路
- ARM的22个常用概念下
- 当年绑架李嘉诚之子后,张子强与李嘉诚对话的细节