\(\\\)

\(Day\ 1\)


\(\\\)

\(\#\ A\) \(Rps\)


定义五种方案的石头剪刀布游戏,两人共进行\(N\)局游戏,已知两人各自的循环节和具体方案,胜者得\(1\)分,败者或平局均不得分,求\(N\)局后两人得分。

  • \(N\in [0,200]\)
  • 将二维的计分表填满,模拟。
#include<cmath>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 210
#define n1 x[0]
#define n2 y[0]
#define R register
#define gc getchar
using namespace std;int n,x[N],y[N];
int res[5][5]={{0,0,1,1,0},{1,0,0,1,0},{0,1,0,0,1},{0,0,1,0,1},{1,1,0,0,0}
};inline int rd(){int x=0; bool f=0; char c=gc();while(!isdigit(c)){if(c=='-')f=1;c=gc();}while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();}return f?-x:x;
}int main(){n=rd(); n1=rd(); n2=rd();for(R int i=1;i<=n1;++i) x[i]=rd();for(R int i=1;i<=n2;++i) y[i]=rd();int px=0,py=0,ansx=0,ansy=0;for(R int i=1;i<=n;++i){px=(px==n1)?1:px+1;py=(py==n2)?1:py+1;ansx+=res[x[px]][y[py]];ansy+=res[y[py]][x[px]];}printf("%d %d",ansx,ansy);return 0;
}

\(\\\)

\(\# B\) \(Link\)


给出一棵\(N\)个节点的树,每个边的边权都为\(1\),每个点都有权值\(W_i\),对于图\(G\)上的任意点对\((u,v)\),若它们的最短距离为\(2\),则它们之间会产生\(W_v \times W_u\)的联合权值,求:

  • 整棵树所有点对中能够产生的最大联合权值
  • 整棵树的所有能产生联合权值的点对间联合权值之和\((\)对\(10007\)取模\()\)
  • \(N\in [0,2\times 10^5]\),\(W_i\in [0,10^4]\)
  • 每个能产生联合权值的点对必然会跨过一个中间点,也就是说,一个能产生联合权值的点对,必然存在一个另外的点,与这个点对中的两个点有边相连。
  • 考虑枚举这个中间点,那么他直接连边的所有点任选两个都会产生联合权值,考虑用一种类似前缀和的方法,顺序扫描所有出边,每个点只与在它前面被扫描到的点\((\)仅本次枚举中间点所扫描到的点\()\)产生联合权值,这样计数可以保证复杂度对于每个点是线性的,并且不会重复计数。
  • 对于最大值部分只需要在扫描过程中记录当前点所引出的点中最大权值点和次大权值点,每扫描一条出边就尝试更新最大值和次大值,最后得到的两个数相乘就是以当前点为中间点所能产生的最大联合权值。
  • 注意点对是有序的,所以求和部分最后要取双倍答案。
#include<cmath>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 200010
#define R register
#define gc getchar
#define mod 10007
using namespace std;int n,tot,ansmx,ans,hd[N],val[N];
struct edge{int to,nxt;}e[N<<1];
inline void add(int u,int v){e[++tot].to=v; e[tot].nxt=hd[u]; hd[u]=tot;
}inline int rd(){int x=0; bool f=0; char c=gc();while(!isdigit(c)){if(c=='-')f=1;c=gc();}while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();}return f?-x:x;
}inline void calc(int u){int sum=0,mx=0,sx=0;for(R int i=hd[u],v;i;i=e[i].nxt){v=e[i].to;if(val[v]>mx){sx=mx;mx=val[v];}else if(val[v]>sx) sx=val[v];(ans+=sum*val[v])%=mod;(sum+=val[v])%=mod;}ansmx=max(ansmx,mx*sx);
}int main(){n=rd();for(R int i=1,u,v;i<n;++i){u=rd(); v=rd(); add(u,v); add(v,u);}for(R int i=1;i<=n;++i) val[i]=rd();for(R int i=1;i<=n;++i) calc(i);printf("%d %d",ansmx,(ans<<1)%mod);return 0;
}

\(\\\)

\(\#C\) \(Bird\)


\(Flappy\ Bird\),问题简化到了二维平面上,规定每次向上一次上升高度和每个位置不上升时的下降高度,具体问题描述见题目链接。

  • \(N\in [1,10^4]\),\(M\in [1,10^3]\)
  • 设\(f[i][j]\)表示处理到第\(i\)列,到达高度为\(j\)的最少点击次数。
  • 有显然的初始化\(f[i][j]=\infty\ \bigg|\ i\in[1,N],j\in[0,M]\),注意到起点不能是地面,所以还有\(f[0][0]=\infty\)。
  • 先不考虑水管高度和下降操作,对于每一个坐标\((i,j)\),有显然的\(\text O(NM^2)\)的转移\(\begin{align} f[i][j]=min\{f[i-1][j-k\times up_i]+k\ \big| \ 1≤k≤\frac{j}{up_i}\}\end{align}\)

  • 注意到转移方程都是统一的形式,\(f[i][j-up_i]\)已经帮助完成了除去\(f[i-1][j-up_i]\)以外的其他部分答案的统计,所以转移可以优化成\(\text O(NM)\)的形式:\(\begin{align}f[i][j]=min(f[i-1][j-up_i],f[i][j-up_i])+1\end{align}\)
  • 注意到顶部的限制,\(f[i][M]\)的转移就多了很多,但是同样可以采用类似的方法优化:\(\begin{align}f[i][M]=min\{f[i][k]+1\ \big|\ k\in [M-up_i,M]\}\end{align}\)
  • 然后再考虑下降部分,之所以这样按排顺序,是因为如果先更新下降部分的策略,可能会导致同一位置下降和上升同时出现,不合法。此部分的转移显然:\(\begin{align} f[i][j]=min(f[i][j],f[i-1][j+dn_i]\ \big|\ j+dn_i\le M) \end{align}\)
  • 最后要考虑继续向后更新的合法性,将水管部分的答案全部重置为\(\infty\)。

  • 答案可以倒着寻找,找到一个位置\(DP\)值不为\(\infty\)的即可作为答案,注意同时要更新经过的水管数。

#include<cmath>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 10010
#define M 1010
#define R register
#define gc getchar
#define inf 2000000000
using namespace std;int n,m,x,u[N],d[N],mx[N],mn[N],f[N][M];inline int rd(){int x=0; char c=gc();while(!isdigit(c)) c=gc();while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();}return x;
}int main(){n=rd(); m=rd(); x=rd();for(R int i=1;i<=n;++i){u[i]=rd(); d[i]=rd(); mx[i]=m; mn[i]=1;}for(R int i=1,p;i<=x;++i){p=rd(); mn[p]=rd()+1; mx[p]=rd()-1;}for(R int i=1;i<=n;++i)for(R int j=0;j<=m;++j) f[i][j]=inf;for(R int i=1;i<=n;++i){for(R int j=1;j<=m;++j){if(j>=u[i]) f[i][j]=min(f[i][j],min(f[i-1][j-u[i]],f[i][j-u[i]])+1);if(j==m) for(R int k=j-u[i];k<=m;++k)f[i][j]=min(f[i][j],min(f[i-1][k],f[i][k])+1);}for(R int j=mn[i];j<=mx[i];++j)if(j+d[i]<=m) f[i][j]=min(f[i][j],f[i-1][j+d[i]]);for(R int j=0;j<mn[i];++j) f[i][j]=inf;for(R int j=mx[i]+1;j<=m;++j) f[i][j]=inf;}int ans=inf,cnt=x;for(R int i=n;i;--i){for(R int j=mn[i];j<=mx[i];++j) ans=min(ans,f[i][j]);if(ans<inf) break;if(mx[i]<m) --cnt;}(cnt==x)?printf("1\n%d\n",ans):printf("0\n%d\n",cnt);return 0;
}

\(\\\)

\(Day\ 2\)


\(\\\)

\(\#\ A\) \(Wireless\)


一个\(130\times 130\)的表格,一些格点有权,现在挑一个格点为中心选一个边长为\(2d\)的正方形,求这个正方形内\((\)含边界\()\)权值和最大值,以及可以产生此最大值的格点个数。

  • \(d\in [1,20]\),\(V_{ij}\in [0,10^6]\)
  • 显然我们可以讲整个表格求二维前缀和,这样即可\(\Theta(1)\)地求出一个子正方形的权值。
  • 把所有格点扫一遍即可,需要注意的是不能直接枚举子正方形顶点,因为会漏掉以边界为中心的一些子正方形,直接按照题目所说枚举中心点即可避免。
#include<cmath>
#include<cstdio>
#include<cctype>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 150
#define R register
#define gc getchar
using namespace std;int n,d,res,cnt=1,sum[N][N];inline int rd(){int x=0; bool f=0; char c=gc();while(!isdigit(c)){if(c=='-')f=1;c=gc();}while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();}return f?-x:x;
}int main(){d=rd(); n=rd();memset(sum,0,sizeof(sum));for(R int i=1,x,y;i<=n;++i){x=rd()+1; y=rd()+1; sum[x][y]+=rd();}for(R int i=1;i<N;++i)for(R int j=1;j<N;++j)sum[i][j]+=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];for(R int i=1;i<=129;++i)for(R int j=1;j<=129;++j){int x=i+d,y=j+d;int ans=sum[x][y]-sum[max(0,x-2*d-1)][y]-sum[x][max(0,y-2*d-1)]+sum[max(0,x-2*d-1)][max(0,y-2*d-1)];if(ans==res) ++cnt;if(ans>res) res=ans,cnt=1;}printf("%d %d\n",cnt,res);return 0;
}

\(\\\)

\(\#B\) \(Road\)


给出一张\(N\)个点\(M\)条边的有向图,且所有边权均为\(1\),现规定起点\(U\)和终点\(V\),找出一条从\(U\)到\(V\)的最短路径,且该路径需满足:路径上的所有点的出边所指向的点都直接或间接与终点连通。

求出符合条件的路径的长度,若不存在一条合法路径则输出"\(-1\)"。

  • \(N\in [2,10^4]\),\(M\in [1,2\times 10^5]\)
  • 把问题转化为最短路,需要去掉所有满足“出边所指向的点中存在不与终点连通的点”的所有点,以及所有不与终点连通的点。
  • 考虑正向求是否可达并不好处理,正难则反,把图建为原图的反图,从\(N\)开始做一遍\(BFS\)即可确定原图中每个点是否与终点连通,这样我们即可去除所有不与终点连通的点。
  • 第一类不合法是由于联通了第二类不合法点导致的,所以在反图中我们同样可以找到原图里联通第二类不合法点的点,把他们也打上不合法标记,注意,这里的标记不能直接在原来存储第二类不合法点的数组中记录

  • 把不合法点都去除后,从\(N\)做一遍最短路即可。

#include<cmath>
#include<queue>
#include<cstdio>
#include<cctype>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 10010
#define M 200010
#define R register
#define gc getchar
#define inf 10000000
using namespace std;bool vis[N],valid[N];
int n,m,tot,hd[N],dis[N],U,V;
struct edge{int to,nxt;}e[M];inline void add(int u,int v){e[++tot].to=v; e[tot].nxt=hd[u]; hd[u]=tot;
}inline int rd(){int x=0; bool f=0; char c=gc();while(!isdigit(c)){if(c=='-')f=1;c=gc();}while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();}return f?-x:x;
}queue<int> q;
inline void bfs(){q.push(V); vis[V]=1;while(!q.empty()){int u=q.front(); q.pop();for(R int i=hd[u],v;i;i=e[i].nxt)if(!vis[v=e[i].to]){q.push(v); vis[v]=1;}}for(R int i=1;i<=n;++i) valid[i]=vis[i];for(R int i=1;i<=n;++i)if(!vis[i]) for(R int j=hd[i];j;j=e[j].nxt) valid[e[j].to]=0;
}priority_queue<pair<int ,int> >h;
inline void dij(){for(R int i=0;i<=n;++i) dis[i]=inf,vis[i]=0;dis[V]=0; h.push(make_pair(0,V));while(!h.empty()){int u=h.top().second; h.pop();if(vis[u]) continue; vis[u]=1;for(R int i=hd[u],v;i;i=e[i].nxt)if(valid[v=e[i].to]&&dis[v]>dis[u]+1){dis[v]=dis[u]+1; h.push(make_pair(-dis[v],v));}}
}int main(){n=rd(); m=rd();for(R int i=1,u,v;i<=m;++i){u=rd(); v=rd(); add(v,u);}U=rd(); V=rd(); bfs(); dij();printf("%d\n",dis[U]==inf?-1:dis[U]);return 0;
}

\(\\\)

\(\#C\) \(Equation\)


已知多项式方程:

\(\begin{align}a_0+a_1x+a_2x^2+\cdots+a_Nx^N=0\end{align}\)

求这个方程在\([1,M]\)内的整数解(\(N\)和\(M\)均为正整数)。

  • \(N\in [1,100]\),\(|a_i|\le 10^{10000}\),\(M\in [0,10^6]\)
  • 秦九韶公式减少方程计算次数,将\(x\)的每一层都嵌套起来,将方程变为如下形式:\(\begin{align}a_0+x(a_1+x(a_2+x(a_3+x(...+xa_n)...)))=0\end{align}\)此时,我们只需计算\(N\)次加法和\(N\)次乘法即可得到等式左边的答案。

  • 枚举\([1,M]\)内的所有数,暴力带入验证即可,注意到系数给的非常大,即使是高精乘法也会超时,我们可以采用哈西的思想,将系数和计算所得都对同一个质数取模,验证最后的答案。这样的做法是不严谨的,所以我们考虑多用几个冲突较少的大质数去完成计算。
  • 下面附的代码在洛谷上可通过,应该是当年\(Noip\)的数据,\(BZOJ\)上的数据加强了,这个版本的代码会超时到死都没有卡过40组数据10s的时限

#include<cmath>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 110
#define M 1000010
#define R register
#define gc getchar
#define mod1 998244353ll
#define mod2 2147483647ll
#define mod3 3221225473ll
using namespace std;
typedef long long ll;ll n,m,res[M],a[3][N];inline void rd(ll p){bool f=0; char c=gc();while(!isdigit(c)){if(c=='-')f=1;c=gc();}while(isdigit(c)){a[0][p]=((a[0][p]<<1)+(a[0][p]<<3)+(c^48))%mod1;a[1][p]=((a[1][p]<<1)+(a[1][p]<<3)+(c^48))%mod2;a[2][p]=((a[2][p]<<1)+(a[2][p]<<3)+(c^48))%mod3;c=gc();}if(f){a[0][p]=-a[0][p]; a[1][p]=-a[1][p]; a[2][p]=-a[2][p];}
}inline bool valid(ll x){ll ans[3]={0ll,0ll,0ll};for(R int i=n;i;--i){ans[0]=(ans[0]+a[0][i])*x%mod1;ans[1]=(ans[1]+a[1][i])*x%mod2;ans[2]=(ans[2]+a[2][i])*x%mod3;}(ans[0]+=a[0][0])%=mod1;(ans[1]+=a[1][0])%=mod2;(ans[2]+=a[2][0])%=mod3;return (ans[0]==0&&ans[1]==0&&ans[2]==0);
}int main(){scanf("%lld%lld",&n,&m);for(R ll i=0;i<=n;++i) rd(i);for(R ll i=1;i<=m;++i) if(valid(i)) res[++res[0]]=i;printf("%lld\n",res[0]);for(R ll i=1;i<=res[0];++i) printf("%lld\n",res[i]);return 0;
}

转载于:https://www.cnblogs.com/SGCollin/p/9574854.html

[ NOIP 2014 ] TG相关推荐

  1. Noip 2014酱油记+简要题解

    好吧,day2T1把d默认为1也是醉了,现在只能期待数据弱然后怒卡一等线吧QAQ Day0 第一次下午出发啊真是不错,才2小时左右就到了233,在车上把sao和fate补掉就到了= = 然后到宾馆之后 ...

  2. NOIP 2014 解方程

    描述 已知多项式方程: a0+a1x+a2x2+...+anxn=0 求这个方程在[1, m]内的整数解(n 和 m 均为正整数). 格式 输入格式 输入共 n+2 行. 第一行包含 2 个整数 n. ...

  3. noip pj,tg酱油记

    D1 先考提高组D1. Description 小凯手中有两种面值的金币,两种面值均为正整数且彼此互素.每种金币小凯都有无数个.在不找零的情况下,仅凭这两种金币,有些物品他是无法准确支付的.现在小凯想 ...

  4. NOIp 2014 #4 无线网络发射器选址 Label:模拟

    题目描述 随着智能手机的日益普及,人们对无线网的需求日益增大.某城市决定对城市内的公共场所覆盖无线网. 假设该城市的布局为由严格平行的129 条东西向街道和129 条南北向街道所形成的网格状,并且相邻 ...

  5. [ NOIP 2008 ] TG

    \(\\\) \(\#A\) \(Word\) 给出一个长为\(N\)的小写字母串,判断出现所有字母中最多出现次数减最少出现次数得到的答案是否是质数. \(N\in [1,100]\) 直接按题意开桶 ...

  6. NOIp 2014 #2 联合权值 Label:图论 !!!未AC

    题目描述 无向连通图G 有n 个点,n - 1 条边.点从1 到n 依次编号,编号为 i 的点的权值为W i ,每条边的长度均为1 .图上两点( u , v ) 的距离定义为u 点到v 点的最短距离. ...

  7. NOIP 2014 联合权值

    题目链接: https://www.luogu.org/problemnew/show/P1351 参考洛谷题解: 使用链式前向星储存图.如果使用深度优先搜索的话,是会超时的,如果遍历中间的点,虽然比 ...

  8. NOIP 2014 Day1 T3飞扬的小鸟

    题目描述:http://codevs.cn/problem/3729/ 表示各种shabi的我编和调了半天,思路大体就是一个完全背包的模型,不过会多一些额外的转移(因为题目限制高度之类的),不过值得注 ...

  9. [ NOIP 1998 ] TG

    \(\\\) \(\#A\) 车站 火车从第\(1\)站开出,上车的人数为\(a\),然后到达第\(2\)站,在第\(2\)站有人上.下车,但上.下车的人数相同,因此在第\(2\)站开出时(即在到达第 ...

最新文章

  1. 访问远程数据库,把远程数据库当做本地库来用
  2. J2SE基础常见面试题目
  3. 【Android 进程保活】oom_adj 值 ( 简介 | 查询进程 PID | 根据进程 PID 查询 oom_adj 值 )
  4. 在IntelliJ IDEA中添加repository模板
  5. 今年你参与开源了吗?
  6. linux+脚本+pid,Linux启动脚本输出pid
  7. You must install signalwire-client-c to build mod_signalwire。
  8. oracle odi 目标数据存储: 临时目标数据存储未与连接关联,ODI知识模块--IKM Oracle Incremental Update...
  9. openbsd运行Linux应用程序,OpenBSD上的服务管理程序rcctl
  10. 小伙面试时被连环追问数据库优化, 面试前如何埋点反杀? 网友看完直呼: 太硬核了!
  11. NR系统概述-架构与演进
  12. 打破传统桎梏,挑战性能巅峰,网友:这轻薄本性能强的像游戏本
  13. solidworks3D打印技术
  14. HC-05蓝牙配对AT指令
  15. pc页面样式自适应的几种方案
  16. Java是什么软件-详细解答Java到底是什么
  17. 关于电脑连接好WiFi却无法使用浏览器上网的一种解决方法
  18. 磨刀不误砍柴工-----为提升自己找到一个平衡点
  19. python怎么筛选excel数据_懂Excel也能轻松入门Python数据分析包pandas(二):高级筛选(上)-excel筛选...
  20. 劳特巴赫trace32使用介绍(一)

热门文章

  1. Leetcode-1154 Ordinal Number Of Date(一年中的第几天)
  2. MOSS 工作流 vs2008+win2008
  3. Python攻克之路-高阶函数
  4. 学生管理系统分层开发
  5. mysql中的trigger
  6. 3 Sum Closest
  7. 利用记录型信号量解决不会出现死锁的哲学家就餐问题
  8. jquery ajax返回html乱码解决
  9. ListView与Button共存问题
  10. window.showModalDialog模态对话框 值回传 TreeView无刷新