• Prob.1 生活大爆炸版 石头剪刀布

模拟。
代码:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int mp[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}};
int A[205],B[205];
int n,lA,lB,ansA,ansB;
int main(){
scanf("%d%d%d",&n,&lA,&lB);
for(int i=1;i<=lA;i++) scanf("%d",&A[i]);
for(int i=1;i<=lB;i++) scanf("%d",&B[i]);
for(int i=1,pA=0,pB=0;i<=n;i++) {
pA++; if(pA>lA) pA=1;
pB++; if(pB>lB) pB=1;
ansA+=mp[A[pA]][B[pB]];
ansB+=mp[B[pB]][A[pA]];
}
printf("%d %d",ansA,ansB);
return 0;
}

    • Prob.2 联合权值

可以叫树形dp吧。
每次考虑把当前子树的根作为长度为2的路径的一个端点或中转点。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#define MAXN 200005
using namespace std;
const int mod=10007;
struct edge{
int to,next;
}e[MAXN*2];
int w[MAXN],head[MAXN];
int sm[MAXN],mx[MAXN];
int n,ent=2,ansx,anss;
void add(int u,int v){
e[ent]=(edge){v,head[u]};
head[u]=ent++;
}
void dfs(int u,int fa){
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v==fa) continue;
dfs(v,u);
anss=(1ll*anss+1ll*sm[v]*w[u]*2)%mod;
anss=(1ll*anss+1ll*sm[u]*w[v]*2)%mod;
sm[u]+=w[v];
ansx=max(ansx,mx[v]*w[u]);
ansx=max(ansx,mx[u]*w[v]);
mx[u]=max(mx[u],w[v]);
}
}
int main(){
scanf("%d",&n);
for(int i=1,u,v;i<n;i++){
scanf("%d%d",&u,&v);
add(u,v); add(v,u);
}
for(int i=1;i<=n;i++) scanf("%d",&w[i]);
dfs(1,0);
printf("%d %d",ansx,anss);
return 0;
}

    • Prob.3 飞扬的小鸟

dp+转移优化
首先 70%的很好想:
dp[i][j]表示到达(i,j)的最小点击次数,显然没有后效性。
             ┌dp[i-1][j+y[i-1]] (不点击)
dp[i][j]=min│
             ┕dp[i-1][j-k*x[i-1]]+k(点击)

这个方程的复杂度为 (n*m*m)
考虑优化,发现这样一个东西:
只考虑"点击"这一个转移来源的话,那么
dp[i][j]只比dp[i][j-x[i-1]]多了一个转移来源。
然后就是一个前缀的思想了,即我们把第二维的j从小到大枚举
那么(这里在说"点击"这一个来源)
dp[i][j]=min(dp[i-1][j-x[i-1]],dp[i][j-x[i-1])+1
这样就把"点击"时的O(n)转移优化为了O(1)。

注意j==m时要特殊处理。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#define INF 0x3f3f3f3f
using namespace std;
int x[10005],y[10005],l[10005],h[10005],fg[10005];
int dp[10005][1005];
int n,m,k,ans=INF;
bool legal(int i,int j){
if(j<=0||j>m) return 0;
if(!fg[i]) return 1;
return l[i]<j&&j<h[i];
}
void cmin(int &a,int b){
if(a>b) a=b;
}
int main(){
scanf("%d%d%d",&n,&m,&k);
memset(dp,0x3f,sizeof(dp));
for(int i=0;i<n;i++) scanf("%d%d",&x[i],&y[i]);
for(int i=1,p;i<=k;i++) scanf("%d",&p),fg[p]=1,scanf("%d%d",&l[p],&h[p]);
for(int j=l[0]+1;j<(fg[0]?h[0]:m+1);j++) dp[0][j]=0;
for(int i=1;i<=n;i++){
//click
for(int j=0;j<m;j++){
int a=legal(i-1,j-x[i-1])?dp[i-1][j-x[i-1]]:INF;
int b=j>x[i-1]?dp[i][j-x[i-1]]:INF;
cmin(dp[i][j],min(a,b)+1);
}
for(int j=m;j>=0;j--){
int a=legal(i-1,j)?dp[i-1][j]:INF;
cmin(dp[i][m],a+max(m-j-1,0)/x[i-1]+1);
}
//no-click
for(int j=0;j<=m;j++){
int a=legal(i-1,j+y[i-1])?dp[i-1][j+y[i-1]]:INF;
cmin(dp[i][j],a);
}
}
for(int i=n;i>=0;i--){
for(int j=1;j<=m;j++){
if(i==n) cmin(ans,dp[i][j]);
if(i!=n&&legal(i,j)&&dp[i][j]<INF){
printf("%d\n%d",0,k);
return 0;
}
}
if(ans<INF) break;
if(fg[i]) k--;
}
printf("%d\n%d",1,ans);
return 0;
}

    • Prob.4 无线网络发射器选址

二维前缀和,求子矩阵和。
千万不要枚举多了。否则会多统计。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int sum[150][150];
int d,n,ans,cnt;
int area(int x1,int y1,int x2,int y2){
return sum[x2][y2]-sum[x1][y2]-sum[x2][y1]+sum[x1][y1];
}
int main(){
scanf("%d%d",&d,&n);
for(int i=1,x,y,k;i<=n;i++){
scanf("%d%d%d",&x,&y,&k);
x++;y++;
sum[x][y]+=k;
}
for(int i=1;i<=129;i++)
for(int j=1;j<=129;j++)
sum[i][j]=sum[i][j]+sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
for(int i=1,x1,y1,x2,y2,now;i<=129;i++)
for(int j=1;j<=129;j++){
x1=max(i-d-1,0); y1=max(j-d-1,0);
x2=min(i+d,129); y2=min(j+d,129);
now=area(x1,y1,x2,y2);
if(now>ans) ans=now,cnt=0;
if(now==ans) cnt++;
}
printf("%d %d",cnt,ans);
return 0;
}

    • Prob.5 寻找道路

反向BFS给无法到终点的点打上标记,
然后再给那些存在一条出边无法到终点的点打上标记。
最后对没有标记的点跑最短路。(因为边权为1,BFS即可)

代码:

#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
struct edge{
int to,next;
}e1[200005],e2[200005];
int head1[10005],head2[10005],vis[10005],dis[10005];
int n,m,ent1=2,ent2=2,S,T;
void add(int u,int v,int &ent,int *head,edge *e){
e[ent]=(edge){v,head[u]};
head[u]=ent++;
}
void BFS1(){
queue<int> q;
vis[T]=1; q.push(T);
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head2[u];i;i=e2[i].next){
int v=e2[i].to;
if(vis[v]) continue;
vis[v]=1; q.push(v);
}
}
for(int u=1;u<=n;u++) if(!vis[u])
for(int i=head2[u];i;i=e2[i].next){
int v=e2[i].to;
if(!vis[v]) continue;
vis[v]=-1;
}
}
void BFS2(){
queue<int>q; q.push(S); dis[S]=1;
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head1[u];i;i=e1[i].next){
int v=e1[i].to;
if(dis[v]||vis[v]!=1) continue;
dis[v]=dis[u]+1;
q.push(v);
}
}
if(dis[T]==0) printf("-1");
else printf("%d",dis[T]-1);
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1,u,v;i<=m;i++)
scanf("%d%d",&u,&v),
add(u,v,ent1,head1,e1),
add(v,u,ent2,head2,e2);
scanf("%d%d",&S,&T);
BFS1();
BFS2();
return 0;
}

    • Prob.6 解方程

又是一大神题,车大佬给我讲了好久才明白。
首先按照题目的意思,我们找出x,要使得:
A0 + A1*X1 + A2*X2 + A3*X3 + ...... + An*Xn == 0  [1]
但是无奈 A的范围很大,无法直接计算。
(然后就阴差阳错的考虑到取模上去)
对等式两边同时取模 M(先只对系数取模)
那么得到:(Bi = Ai % M)
B0 + B1*X1 + B2*X2 + B3*X3 + ...... + Bn*Xn == 0  [2]
然后动动脑子,可以发现满足 [1]式的x 则是一定满足 [2]式的x。

!!!
那么我们是不是可以把原来的 [1]式 通过取模后得到系数较小的 [2]式,
然后通过 可以计算的[2]式来找合法的x。

好吧,显然有错。
虽然满足 [1]式的x  一定是满足 [2]式的x,
但是满足 [2]式的x  却不一定是满足[1]式的x。(这个好理解吧)
显然满足 [2]式的x,带入[1]式左边,可能得到两个值,一个是0(合法),一个是k * M(非法)

那怎么办? 接下来就神奇了。
我们多选几个 M(5-6个) : M1 , M2 , M3 ,M4 , M5(M尽量为大素数或某些大素数的乘积
那么对于一个x,在这5种M取模下,如果都满足 [2]式(即其值==0),那么这个x就非常可能是满足 [1]式的,直接把它当做答案。

为什么呢。
如果都满足,那么把这个 x 带入 [1]式后,得到的值要么为 0(合法),要么为 k * M1M2M3M4M5(非法)。
(对于非法的 x,就是带入 [1]式后,其值==k *  M1M2M3M4M5,即是"我们选取的这几个模值的乘积的倍数"。)
而对于所有的x,带入 [1]式后,最多产生 10^6个值。
那么在出题人不知道我们选取的模值的情况下,要使得某个x带入 [1]式后恰好等于"我们选取的模数的乘积的倍数"的几率是很小的。

所以,除非运气不好,否则我们选的几个M (强调:M尽量为大素数或某些大素数的乘积),就可以达到筛选出正确的x的目的。

#include<cctype>
#include<cstdio>
#include<cstring>
#include<iostream>
#define _ %mod[j]
using namespace std;
const int mod[6]={13923, 16851, 24989, 19997, 11987, 13999};
int val[1000005][6]/*mod意义下*/,A[105][6],ANS[1000005];
int n,m,cnt;
void readai(){
int fu;char ch; ch=getchar();
for(int i=0;i<=n;i++){
fu=1;
while(!isdigit(ch)){
if(ch=='-') fu=-1;
ch=getchar();
}
while(isdigit(ch)){
for(int j=0;j<=5;j++)
A[i][j]=(A[i][j]*10+(ch-'0'))_;
ch=getchar();
}
for(int j=0;j<=5;j++) A[i][j]*=fu;
}
}
int Pow(int a,int b,int j){
int now=1;
while(b){
if(b&1) now=(1ll*now*a)_;
a=(1ll*a*a)_;
b>>=1;
}
return now;
}
int cal(int x,int j){
int ans=0;
for(int i=0;i<=n;i++)
ans=(ans+(1ll*A[i][j]*Pow(x,i,j))_)_;
return ans;
}
int main(){
scanf("%d%d",&n,&m);
readai();
for(int j=0;j<=5;j++)
for(int i=1;i<mod[j];i++)
val[i][j]=cal(i,j);
for(int i=1;i<=m;i++){
bool fg=1;
for(int j=0;j<=5;j++)
if(val[(i)_][j]) fg=0;
if(fg) ANS[++cnt]=i;
}
printf("%d\n",cnt);
for(int i=1;i<cnt;i++) printf("%d\n",ANS[i]);
printf("%d",ANS[cnt]);
return 0;
}

NOIP 2014的更多相关文章

  1. NOIP 2014 提高组 题解

    NOIP 2014 提高组 题解 No 1. 生活大爆炸版石头剪刀布 http://www.luogu.org/problem/show?pid=1328 这是道大水题,我都在想怎么会有人错了,没算法 ...

  2. Luogu 1351 NOIP 2014 联合权值(贪心,计数原理)

    Luogu 1351 NOIP 2014 联合权值(贪心,计数原理) Description 无向连通图 G 有 n 个点,n-1 条边.点从 1 到 n 依次编号,编号为 i 的点的权值为 Wi, ...

  3. noip 2014 提高组初赛

    noip 2014 提高组初赛 一. TCP协议属于哪一层协议( ) A. 应用层 B. 传输层 C. 网络层 D. 数据链路层 B TCP(传输控制协议) 若有变量int a; float: x, ...

  4. 洛谷P1328==codevs3716 生活大爆炸版石头剪刀布[NOIP 2014 day1 T1]

    P1328 生活大爆炸版石头剪刀布 1.8K通过 2.6K提交 题目提供者2014白永忻 标签模拟NOIp提高组2014 难度普及- 提交该题 讨论 题解 记录 最新讨论 Who can help m ...

  5. noip 2014 总结

    2014 年的noip 已经结束了,成绩从个人而言不是特别的理想,从今年题的逗的程度,本来是个xxx 就被玩脱了= = 当然现在后悔事没有用的了,不过第二天全屏技术的在最后一小时看到了两道题的错误,然 ...

  6. NOIP 2014 pj & tg

    由于我太弱,去了pj组= = ============================== T1: 傻逼暴力 T2: 傻逼暴力+判断+更新 T3: 手画一下就知道了.算出这个点在第几圈,再使劲yy下在 ...

  7. [NOIP 2014复习]第三章:动态规划——NOIP历届真题回想

    背包型动态规划 1.Wikioi 1047 邮票面值设计 题目描写叙述 Description 给定一个信封,最多仅仅同意粘贴N张邮票,计算在给定K(N+K≤40)种邮票的情况下(假定全部的邮票数量都 ...

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

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

  9. NOIP 2014 提高组 Day1

    期望得分:100+100+50=250 实际得分:100+100+50=250 此次NOIP  ZJ省一分数线:500,SD:345 https://www.luogu.org/problem/lis ...

  10. [ NOIP 2014 ] TG

    \(\\\) \(Day\ 1\) \(\\\) \(\#\ A\) \(Rps\) 定义五种方案的石头剪刀布游戏,两人共进行\(N\)局游戏,已知两人各自的循环节和具体方案,胜者得\(1\)分,败者 ...

随机推荐

  1. Android开发简易教程

    Android开发简易教程 Android 开发因为涉及到代码编辑.UI 布局.打包等工序,有一款好用的IDE非常重要.Google 最早提供了基于 Eclipse 的 ADT 作为开发工具,后来在2 ...

  2. Ionic3的HTTP请求方法

    Ionic的http请求方法,一种是使用Ionic的Native的Http方法,另一种是使用Angular的Http请求方法. 第一种真的是看着文档都实现不了,很奇怪的错(官网文档:https://i ...

  3. C程序设计-----第1次作业

    一. PTA作业.    在完成PTA作业的时候我没有认真读题.每次都是提交完整代码 6-1(1) #include <stdio.h> //P++等价于(p)++还是等价于*(p++)? ...

  4. 201621123057 《Java程序设计》第5周学习总结

    1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 接口,interface,implements,方法签名,has-a,Comparable,Comparator. 1.2 尝试 ...

  5. Hibernate与mysql的对应类型

    Hibernate映射类型 Java类型 标准SQL类型  integer  java.lang.Integer  integer  long  java.lang.Long  bigint  sho ...

  6. 学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  7. Python内置函数(7)——sum

    英文文档: sum(iterable[, start]) Sums start and the items of an iterable from left to right and returns ...

  8. CentOS7下安装python-pip

    一.检查是否已经安装 检查linux有没有安装python-pip包,直接执行:: yum install python-pip 二.安装 pip install 1.没有python-pip包就执行 ...

  9. JMeter入门(03)多台JMeter联合测试

    一.配置各个节点 1.配置jmeter.properties # Remote Hosts - comma delimited#remote_hosts=localhost:1099,localhos ...

  10. Spring Security入门(2-3)Spring Security 的运行原理 3

    关键组件关系 FilterSecurityInterceptor--- authenticationManager --- UserDetailService--- accessDecisionMan ...