NOIP2017提高组模拟赛 8(总结)##

第一题 路径

	在二维坐标平面里有N个整数点,Bessie要访问这N个点。刚开始Bessie在点(0,0)处。 每一步,Bessie可以走到上、下、左、右四个点。即假设Bessie当前所在点的坐标是(x,y),那么它下一步可以移动到(x,y+1), (x,y-1), (x+1,y), (x-1,y)之一。
Bessie目标是找到一个移动序列,满足下面的条件:
1、从点(0,0)出发。
2、对于给定的那N个点,每个点至少被访问一次。
3、可以选择那N个给定点中任意一个作为结束点。
现在为了增加难度,农夫规定Bessie走过的所有步数之和的奇偶性必须为wantedParity,显然wantedParity 是0或1,是题目给定的,0表示偶,1表示奇。Bessie立刻感觉到了难度的增加,如果存在满足条件的移动序列,那么输出CAN,否则输出CANNOT。

  一个定理,假如点i到点j有一条路径是偶数,那么其他路径也一定是偶数(最短距离需要的上下左右是固定的,多余的上和下抵消,多余的左和右抵消),反之亦然。

  简单的证明,假如需要的是偶数,那么只需判断是否存在一个点到(0,0)的距离是偶数就行了(作为终点),其它点可以从(0,0)出发到(xi,yi)再回到(0,0),这样肯定为偶数步数。需要的是奇数的也类似。

#include<cstdio>
#include<algorithm>
#include<cmath> #define imax(a,b) ((a>b)?(a):(b))
#define imin(a,b) ((a<b)?(a):(b)) typedef long long ll; using namespace std; int ng,n,ne,a,b,s[5]; int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
scanf("%d",&ng);
while(ng--)
{
scanf("%d%d",&n,&ne);
s[0]=s[1]=0;
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a,&b);
int c=abs(a)+abs(b);
s[c&1]++;
}
if(ne==0)
{
if(s[0]>0) printf("CAN\n"); else printf("CANNOT\n");
} else
if(ne==1)
{
if(s[1]>0) printf("CAN\n"); else printf("CANNOT\n");
}
}
return 0;
}

第二题 冠军

	有N个拳手参加擂台赛,这个人的编号是0至N-1。有N个位置,编号从0至N-1。每个位置分配一个拳手,显然共有N!种不同的分配方案。
对于一种具体的分配方案,站在位置0的拳手与站在位置1的拳手比赛,胜者进入下一轮,败者被淘汰。站在位置2的拳手与站在位置3的拳手比赛,胜者进入下一轮,败者被淘汰,同样道理,站在位置4的拳手与站在位置5的拳手比赛,胜者进入下一轮,败者被淘汰。。。最终会产生一个冠军拳手。
如下图所示:

	已知N一定是2的若干次幂,而且不超过16,也就是说N是{2,4,8,16}之中的某一个数。
现在的问题是:有多少种不同的分配方案,使得第i个选手能最终成为冠军?不妨假设该数值是ans[i]。
你的任务就是输出:ans[0]、ans[1]、....ans[N-1]。

  一道状压DP题,不过要注意优化,过多的无用状态没过滤掉会被卡。

  若beat[i][j]'Y'  F[S][i]+=F[S1][i]*F[S-S1][j]

  若beat[i][j]'N'  F[S][j]+=F[S1][i]*F[S-S1][j]

  F[S][i]表示选了S这几个拳手(2进制,0为不选,1为选),最终胜利的拳手为i的方案数。

  结果会爆INT,要用LONG LONG来存。

  (PS:一开始,码了搜索去找状态,结果WA了,机子单步不了,又找不出哪里错。后来比赛结束重新码了程序才过。)

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath> #define imax(a,b) ((a>b)?(a):(b))
#define imin(a,b) ((a<b)?(a):(b))
#define pd(S,i) ((S&(1<<(i-1)))>0) typedef long long ll; using namespace std; const int MP=100500;
int n,hn,nn,B[20],C[20];
char st[20];
bool ff[20][20];
int Go[6][MP],Set[6][MP],one[MP],A[20];
ll f[MP][20]; int main()
{
freopen("b.in","r",stdin);
freopen("b.out","w",stdout);
scanf("%d",&n); hn=n>>1;
nn=(1<<n);
for(int i=1;i<=n;i++)
{
scanf("%s",st);
for(int j=1;j<=n;j++) ff[i][j]=(st[j-1]=='Y');
}
one[0]=0;
for(int i=1;i<nn;i++) one[i]=one[i>>1]+(i&1);
for(int i=1;i<nn;i++)
{
if(one[i]==1) { Set[0][++Set[0][0]]=i; if(i<(1<<2)) Go[0][++Go[0][0]]=i; } else
if(one[i]==2) { Set[1][++Set[1][0]]=i; if(i<(1<<4)) Go[1][++Go[1][0]]=i; } else
if(one[i]==4) { Set[2][++Set[2][0]]=i; if(i<(1<<8)) Go[2][++Go[2][0]]=i; } else
if(one[i]==8) { Set[3][++Set[3][0]]=i; if(i<(1<<16)) Go[3][++Go[3][0]]=i; }
}
for(int i=1;i<=Set[0][0];i++)
{
int S=Set[0][i];
for(int j=1;j<=n;j++)
if(pd(S,j)) f[S][j]=1;
}
Set[4][0]=1; Set[4][1]=(1<<16)-1;
int go=0;
if(n==16) go=4; else
if(n==8) go=3; else
if(n==4) go=2; else go=1;
for(int ho=1;ho<=go;ho++)
{
for(int i=1;i<=Set[ho][0];i++)
{
int S=Set[ho][i],S1; A[0]=0;
for(int j=1;j<=n;j++)
if(pd(S,j)) A[++A[0]]=j;
for(int h=1;h<=Go[ho-1][0];h++)
{
int ss=Go[ho-1][h]; S1=0;
B[0]=0; C[0]=0;
for(int k=1;k<=(1<<ho);k++)
{
if(pd(ss,k))
{
S1|=(1<<(A[k]-1));
B[++B[0]]=A[k];
} else C[++C[0]]=A[k];
}
for(int fa=1;fa<=B[0];fa++)
for(int fb=1;fb<=C[0];fb++)
if(ff[B[fa]][C[fb]]) f[S][B[fa]]+=f[S1][B[fa]]*f[S-S1][C[fb]];
else f[S][C[fb]]+=f[S1][B[fa]]*f[S-S1][C[fb]];
}
}
}
for(int i=1;i<=n;i++) printf("%I64d\n",f[nn-1][i]);
return 0;
}

第三题 指纹

	随着科技的发展,当今很多企业向社会推出了越来越多的结合指纹识别技术的高科技产品。其中以需要进行身份验证或身份识别类型的产品居多,如门禁系统、手提电脑、指纹硬盘。
对任何生物识别系统来说,输入数据的质量对于系准确率有着重大的影响。为了获得较高质量的指纹图像,近年来指纹采集设备不断地被更新,各种先进的指纹采集技术也逐渐被引入到实际产品中。尽管如此,由于手指皮肤情况、空气湿度、灰尘等一些因素的影响,依旧存在着大量的质量不高的指纹图像。
通常我们可以通过编号为A,B,C,D的四个属性来评估一个指纹图像的质量的高低:
A为杂点的数量;B为折痕的数量;C为脊线断续程度;D为脊线粘连程度。这四个属性值越小表示该图像在相应方面表现越优。
由于指纹图质量评估研究的需要,我们通过对一个人的指纹进行多次采样后得到多个不同质量的指纹图像,并将其各质量属性记录在一个数据库中(不同图像的各属性值均不相同)。对于两个指纹图像,单个属性的好坏并不能说明图像质量的高低。比如图像1杂点数比图像2的少,但有可能图像1的粘连程度比图像2高得多,因此不能武断地认为图像1就比图像2好。
但是如果一个图像有不少于三个属性都优于另一个图像,那么我们有理由相信前者的质量要优于后者。对于数据库中的一个指纹图像I,如果存在另一个图像J,J有不少于三个质量属性优于图像I,那么我们认为图像I是一种“累赘”。
为了减少指纹图像数据库的大小,我们希望去除其中的累赘图像,现在实验室需要你的帮忙,找出该部分图像。为方便就算,我们已经分别按四个属性,计算出了所有图像按该属性的优劣程度排序的名次。

  这题比前一题好打多了,不过一直在调第二题,这题便没有做……

  每一个指纹有四个参数ABCD

  先考虑ABC,因为假设i的D很小,但ABC很大,那么它也会被刷掉。

  按A排序,用B作为下标,存C。用线段树维护一段区间的最小值。

  A从小到大排序,对于i来说,比它的A小的都已经加入了线段树中,若findmin(1,B)比C小,证明一定存在x的ABC均小于i,那么i也没有存在的意义了(打del标记)。

  再考虑ABD,ACD,BCD,一共四种情况,逐一筛掉无用的指纹就行了。

#include<cstdio>
#include<algorithm>
#include<cmath> #define imax(a,b) ((a>b)?(a):(b))
#define imin(a,b) ((a<b)?(a):(b)) typedef long long ll; using namespace std; const int oo=1e9;
const int N=1e5;
struct data { int a,b,c,d,id; } d[N+100],dg[N+100];
int n;
bool ffg[N+100];
int tree[N<<2]; bool cmp(data A,data B) { return (A.a<B.a); } void build(int ro,int L,int R)
{
if(L==R) { tree[ro]=oo; return; }
int Mid=(L+R)>>1;
build(ro<<1,L,Mid); build(ro<<1|1,Mid+1,R);
tree[ro]=imin(tree[ro<<1],tree[ro<<1|1]);
} void pre(int ho)
{
for(int i=1;i<=n;i++) dg[i]=d[i];
if(ho==1) for(int i=1;i<=n;i++) swap(dg[i].c,dg[i].d); else
if(ho==2) for(int i=1;i<=n;i++) swap(dg[i].b,dg[i].d); else
if(ho==3) for(int i=1;i<=n;i++) swap(dg[i].a,dg[i].d);
sort(dg+1,dg+1+n,cmp);
build(1,1,n);
} void updata(int ro,int L,int R,int x,int val)
{
if(L>x || R<x) return;
if(L==x && x==R)
{
tree[ro]=val; return;
}
int Mid=(L+R)>>1;
updata(ro<<1,L,Mid,x,val); updata(ro<<1|1,Mid+1,R,x,val);
tree[ro]=imin(tree[ro<<1],tree[ro<<1|1]);
} int query(int ro,int L,int R,int li,int ri)
{
if(L>ri || R<li) return oo;
if(li<=L && R<=ri) return tree[ro];
int Mid=(L+R)>>1;
int x1=query(ro<<1,L,Mid,li,ri),x2=query(ro<<1|1,Mid+1,R,li,ri);
return (imin(x1,x2));
} int main()
{
freopen("c.in","r",stdin);
freopen("c.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d%d%d%d",&d[i].a,&d[i].b,&d[i].c,&d[i].d),d[i].id=i;
for(int ho=0;ho<4;ho++)
{
pre(ho);
for(int i=1;i<=n;i++)
{
int temp=query(1,1,n,1,dg[i].b);
if(temp<dg[i].c) ffg[dg[i].id]=1;
updata(1,1,n,dg[i].b,dg[i].c);
}
}
int dell=0;
for(int i=1;i<=n;i++) dell+=ffg[i];
printf("%d\n",dell);
for(int i=1;i<=n;i++)
if(ffg[i]) printf("%d\n",i);
return 0;
}

NOIP2017提高组模拟赛 8(总结)的更多相关文章

  1. NOIP2017提高组 模拟赛15(总结)

    NOIP2017提高组 模拟赛15(总结) 第一题 讨厌整除的小明 [题目描述] 小明作为一个数学迷,总会出于数字的一些性质喜欢上某个数字,然而当他喜欢数字k的时候,却十分讨厌那些能够整除k而比k小的 ...

  2. NOIP2017提高组 模拟赛13(总结)

    NOIP2017提高组 模拟赛13(总结) 第一题 函数 [题目描述] [输入格式] 三个整数. 1≤t<10^9+7,2≤l≤r≤5*10^6 [输出格式] 一个整数. [输出样例] 2 2 ...

  3. NOIP2017提高组模拟赛 10 (总结)

    NOIP2017提高组模拟赛 10 (总结) 第一题 机密信息 FJ有个很奇怪的习惯,他把他所有的机密信息都存放在一个叫机密盘的磁盘分区里,然而这个机密盘中却没有一个文件,那他是怎么存放信息呢?聪明的 ...

  4. NOIP2017提高组模拟赛 9 (总结)

    NOIP2017提高组模拟赛 9 (总结) 第一题 星星 天空中有N(1≤N≤400)颗星,每颗星有一个唯一的坐标(x,y),(1≤x,y ≤N).请计算可以覆盖至少K(1≤K≤N)颗星的矩形的最小面 ...

  5. NOIP2017提高组模拟赛 7(总结)

    NOIP2017提高组模拟赛 7(总结) 第一题 斯诺克 考虑这样一个斯诺克球台,它只有四个袋口,分别在四个角上(如下图所示).我们把所有桌子边界上的整数点作为击球点(除了4个袋口),在每个击球点我们 ...

  6. NOIP2017提高组模拟赛5 (总结)

    NOIP2017提高组模拟赛5 (总结) 第一题 最远 奶牛们想建立一个新的城市.它们想建立一条长度为N (1 <= N <= 1,000,000)的 主线大街,然后建立K条 (2 < ...

  7. NOIP2017提高组模拟赛4 (总结)

    NOIP2017提高组模拟赛4 (总结) 第一题 约数 设K是一个正整数,设X是K的约数,且X不等于1也不等于K. 加了X后,K的值就变大了,你可以重复上面的步骤.例如K= 4,我们可以用上面的规则产 ...

  8. 计蒜客NOIP2017提高组模拟赛(三)day1

    火山喷发 火山喷发对所有附近的生物具有毁灭性的影响.在本题中,我们希望用数值来模拟这一过程. 在环境里有 n 个生物分别具有 A​1​​,A​2​​,⋯,A​n​​点生命值,一次火山喷发总计 MM 轮 ...

  9. 计蒜客NOIP2017提高组模拟赛(四)day1

    T1:小X的质数 小 X 是一位热爱数学的男孩子,在茫茫的数字中,他对质数更有一种独特的情感.小 X 认为,质数是一切自然数起源的地方. 在小 X 的认知里,质数是除了本身和 1 以外,没有其他因数的 ...

随机推荐

  1. 【翻译自mos文章】 11gR1版本号 asmcmd的新命令--cp、md_backup、md_restore

    11gR1版本号 asmcmd的新命令--cp.md_backup.md_restore 參考原文: ASMCMD - New commands in 11gR1 (Doc ID 451900.1) ...

  2. HDU 1113 Word Amalgamation (map 容器 + string容器)

    http://acm.hdu.edu.cn/showproblem.php?pid=1113 Problem Description In millions of newspapers across ...

  3. 使用fiddler模拟http get

    wireshark抓到一个http get数据包 GET /Hero/zhCN/client/alert?build=zhCN&targetRegion=0&homeCountry= ...

  4. 了解和解决SQL SERVER阻塞问题(copy)

    http://support.microsoft.com/kb/224453 Summary In this article, the term "connection" refe ...

  5. struts2学习之基础笔记5

    第十章 Struts 2的输入校验 1 Struts 2 输入校验原理 a . 分类 validate()方法校验 b . validation框架校验 2 valibate()方法校验实现 步骤  ...

  6. 微信小程序中获取高度及设备的方法

    由于js中可以采用操纵dom的方法来获取页面元素的高度,可是在微信小程序中不能操纵dom,经过查找之后发现仅仅只有以下几个方法可以获取到高度 wx.getSystemInfoSync().window ...

  7. android 打包工具

    sdk.jar-修改路径-JarToDex-DexToSmali-复制文件

  8. Mac-O文件加载的全过程(一)

    在Mac的开发中, 有没有想过当我们点击可执行文件之后,Mac究竟做了什么事情才让我们的程序运行起来? 对于应用层开发人员或者普通的用户而言, 其实无需知道的这么详细:但是对于内核开发人员而言, 如果 ...

  9. css——权重叠加

    权重叠加 在下面的一段代码中,第一个样式body b有两个标签,第二个有一个标签b.两个中都有color,会应用哪一个呢?果是 那下面的代码会显示什么样的结果 结果是 应用的事body b中的colo ...

  10. [读书笔记] R语言实战 (四) 基本数据管理

    1. 创建新的变量 mydata<-data.frame(x1=c(2,2,6,4),x2=c(3,4,2,8)) #方法一 mydata$sumx<-mydata$x1+mydata$x ...