11.14 noip模拟试题
题目名称 |
正确答案 |
序列问题 |
长途旅行 |
英文名称 |
answer |
sequence |
travel |
输入文件名 |
answer.in |
sequence.in |
travel.in |
输出文件名 |
answer.out |
sequence.out |
travel.out |
时间限制 |
1s |
1s |
1s |
空间限制 |
256M |
256M |
256M |
测试点数目 |
20 |
20 |
10 |
测试点分值 |
5 |
5 |
10 |
是否有部分分 |
无 |
无 |
无 |
题目类型 |
传统 |
传统 |
传统 |
是否有SPJ |
无 |
无 |
无 |
1.正确答案
【题目描述】
小H与小Y刚刚参加完UOIP外卡组的初赛,就迫不及待的跑出考场对答案。
“吔,我的答案和你都不一样!”,小Y说道,”我们去找神犇们问答案吧”。
外卡组试卷中共有m道判断题,小H与小Y一共从其他n个神犇那问了答案。之后又从小G那里得知,这n个神犇中有p个考了满分,q个考了零分,其他神犇不为满分或零分。这可让小Y与小H犯了难。你能帮助他们还原出标准答案吗?如有多解则输出字典序最小的那个。无解输出-1。
【输入格式】
第一行四个整数n, m, p, q,意义如上描述。
接下来n行,每一行m个字符’N’或’Y’,表示这题这个神犇的答案。
【输出格式】
仅一行,一个长度为m的字符串或是-1。
【样例输入】
2 2 2 0
YY
YY
【样例输出】
YY
【数据范围】
30% : n <= 100.
60% : n <= 5000 , m <= 100.
100% : 1 <= n <= 30000 , 1 <= m
<= 500. 0 <= p , q 且 p + q <= n.
懒得写hash map水过
#include<cstdio>
#include<iostream>
#include<map>
#include<cstring>
#include<algorithm>
#define maxn 30010
using namespace std;
int n,m,p,q,falg;
char ss[maxn];
string s[maxn],ans;
map<string,int>f;
void Solve1(){
for(int i=;i<=n;i++){
int x=f[s[i]];
if(x!=p)continue;
string now;now.clear();
for(int k=;k<m;k++)
now+=(s[i][k]=='Y'?'N':'Y');
int y=f[now];
if(y==q){
falg=;ans=s[i];break;
}
}
}
void Solve2(){
for(int i=;i<=n;i++){
int x=f[s[i]];
if(x!=p)continue;
string now;now.clear();
for(int k=;k<m;k++)
now+=(s[i][k]=='Y'?'N':'Y');
int y=f[now];
if(y==q){
falg=;ans=s[i];break;
}
}
}
void Solve3(){
for(int i=n;i>=;i--){
int x=f[s[i]];
if(x!=q)continue;
string now;now.clear();
for(int k=;k<m;k++)
now+=(s[i][k]=='Y'?'N':'Y');
int y=f[now];
if(y==p){
falg=;ans=now;break;
}
}
}
void Solve4(){ int A[]={};
while(){
string now,noww;
now.clear();noww.clear();
for(int i=;i<=m;i++)
if(A[i])now+='Y';
else now+='N';
for(int i=;i<=m;i++)
if(A[i])noww+='N';
else noww+='Y';
int x=f[now],y=f[noww];
if(!x&&!y){
falg=;ans=now;break;
}
int can=;
for(int i=m;i>=;i--)
if(A[i]==){
A[i]=;can=;
for(int j=i+;j<=m;j++)
A[j]=;can=;break;
}
if(!can)break;
}
}
int main()
{
freopen("answer.in","r",stdin);
freopen("answer.out","w",stdout);
scanf("%d%d%d%d",&n,&m,&p,&q);
for(int i=;i<=n;i++){
scanf("%s",ss);
for(int j=;j<m;j++)
s[i]+=ss[j];
f[s[i]]++;
}
sort(s+,s++n);
if(p&&q)Solve1();
else if(p&&!q)Solve2();
else if(!p&&q)Solve3();
else if(!p&&!q)Solve4();
if(falg)cout<<ans<<endl;
else cout<<"-1"<<endl;
return ;
}
2.序列问题
【题目描述】
小H是个善于思考的学生,她正在思考一个有关序列的问题。
她的面前浮现出了一个长度为n的序列{ai},她想找出两个非空的集合S、T。
这两个集合要满足以下的条件:
1. 两个集合中的元素都为整数,且都在 [1, n] 里,即Si,Ti ∈ [1, n]。
2. 对于集合S中任意一个元素x,集合T中任意一个元素y,满足x < y。
3. 对于大小分别为p, q的集合S与T,满足
a[s1] xor a[s2] xor a[s3] ... xor a[sp] = a[t1] and a[t2] and a[t3] ... and a[tq].
小H想知道一共有多少对这样的集合(S,T),你能帮助她吗?
【输入格式】
第一行,一个整数n
第二行,n个整数,代表ai。
【输出格式】
仅一行,表示最后的答案。
【样例输入】
4
1 2 3 3
【样例输出】
4
【样例解释】
S = {1,2}, T = {3}, 1 ^ 2 = 3 = 3 (^为异或)
S = {1,2}, T = {4}, 1 ^ 2 = 3 = 3
S = {1,2}, T = {3,4} 1 ^ 2 = 3 & 3 = 3 (&为与运算)
S = {3}, T = {4} 3 = 3 = 3
【数据范围】
30%:
1 <= n <= 10
60%:
1 <= n <= 100
100%:
1 <= n <= 1000, 0 <= ai < 1024
30暴力
/*暴力30*/
#include<cstdio>
#define maxn 1010
using namespace std;
int n,a[maxn],A[maxn],B[maxn],ans;
void Dfs(int now,int x,int y){
if(now==n+){
if(A[A[]]>=B[])return;
if(x==y&&A[]&&B[])
ans++;return;
}
Dfs(now+,x,y);
A[++A[]]=now;Dfs(now+,x^a[now],y);A[A[]--]=;
B[++B[]]=now;Dfs(now+,x,y&a[now]);B[B[]--]=;
}
int main(){
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
scanf("%d",&n);
if(n>){
printf("0\n");return ;
}
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
Dfs(,,);
printf("%d\n",ans);
fclose(stdin);fclose(stdout);
return ;
}
dp
/*
再一次没有写出dp来 感觉noip出个dp题要跪了22333
这是个问题....
想到了 f g 分别表示啥
然后发现 有重复 会重复计算很多
然后发现可以定义成 一定选了这个的状态
然后又有一个问题
枚举分开点的话 又会漏了许多
这就尴尬了.....
解决方法是确定g选这个 然后f用前缀和
嗯 很机智
*/
#include<cstdio>
#include<cstring>
#define maxn 1010
using namespace std;
int n,a[maxn],b[maxn];
long long f[maxn][],g[maxn][],sum[],ans;
int main()
{
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
for(int i=;i<=n;i++)
b[i]=a[n-i+];
for(int i=;i<n;i++){
for(int j=;j<;j++)
f[i+][j^a[i+]]+=sum[j];
f[i+][a[i+]]++;
for(int j=;j<;j++)
sum[j]+=f[i+][j];
}
memset(sum,,sizeof(sum));
for(int i=;i<n;i++){
for(int j=;j<;j++)
g[i+][j&b[i+]]+=sum[j];
g[i+][b[i+]]++;
for(int j=;j<;j++)
sum[j]+=g[i+][j];
}
memset(sum,,sizeof(sum));
for(int i=;i<=n;i++){
for(int j=;j<;j++)
sum[j]+=f[i][j];
for(int j=;j<;j++)
ans+=sum[j]*g[n-i][j];
}
printf("%I64d\n",ans);
return ;
}
/*超时爆空间的压位高精 好吧dp写丑了 导致高精不好办了2333*/
#include<cstdio>
#include<iostream>
#include<cstring>
#define maxn 1001
#define ll long long
#define bas 1000000000
using namespace std;
int n,a[maxn],b[maxn];
ll f[maxn][][],g[maxn][][],sum[][],ans[],A[];
void Add(ll a[],ll b[]){
int len=max(a[],b[]),c[]={};
for(int i=;i<=len;i++)
c[i]=a[i]+b[i];
for(int i=;i<=len;i++)
if(c[i]>=bas){
c[i+]++;c[i]%=bas;
}
if(c[len+])len++;c[]=len;
for(int i=;i<=c[];i++)a[i]=c[i];
}
void Mul(ll a[],ll b[]){
memset(A,,sizeof(A));
for(int i=;i<=a[];i++){
for(int j=;j<=b[];j++){
A[i+j-]+=a[i]*b[j];
if(A[i+j-]>=bas){
A[i+j]+=A[i+j-]/bas;
A[i+j-]%=bas;
}
}
int len=i+b[]-;
while(A[len+]){
len++;A[len+]+=A[len]/bas;A[len]%=bas;
}
}
for(int i=a[]+b[];i>=;i--)
if(A[i]){
A[]=i;break;
}
}
int main()
{
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
cin>>n;
for(int i=;i<=n;i++)
cin>>a[i];
for(int i=;i<=n;i++)
b[i]=a[n-i+];
A[]=;A[]=;
for(int i=;i<n;i++){
for(int j=;j<;j++)
Add(f[i+][j^a[i+]],sum[j]);
Add(f[i+][a[i+]],A);
for(int j=;j<;j++)
Add(sum[j],f[i+][j]);
}
memset(sum,,sizeof(sum));
for(int i=;i<n;i++){
for(int j=;j<;j++)
Add(g[i+][j&b[i+]],sum[j]);
Add(g[i+][b[i+]],A);
for(int j=;j<;j++)
Add(sum[j],g[i+][j]);
}
memset(sum,,sizeof(sum));
for(int i=;i<=n;i++){
for(int j=;j<;j++)
Add(sum[j],f[i][j]);
for(int j=;j<;j++){
Mul(sum[j],g[n-i][j]);
Add(ans,A);
}
}
printf("%lld",ans[ans[]]);
for(int i=ans[]-;i>=;i--)
printf("%09lld",ans[i]);
printf("\n");
return ;
}
(dp写丑了 导致高精炸了2333)
3.长途旅行
【题目描述】
JY是一个爱旅游的探险家,也是一名强迫症患者。现在JY想要在C国进行一次长途旅行,C国拥有n个城市(编号为0,1,2...,n - 1),城市之间有m条道路,可能某个城市到自己有一条道路,也有可能两个城市之间有多条道路,通过每条道路都要花费一些时间。JY从0号城市开始出发,目的地为n – 1号城市。由于JY想要好好参观一下C国,所以JY想要旅行恰好T小时。为了让自己的旅行更有意思,JY决定不在任何一个时刻停留(走一条到城市自己的路并不算停留)。JY想知道是否能够花恰好T小时到达n – 1号城市(每个城市可经过多次)。现在这个问题交给了你。
若可以恰好到达输出“Possible”否则输出“Impossible”。(不含引号)。
【输入格式】
第一行一个正整数Case,表示数据组数。
每组数据第一行3个整数,分别为n, m, T。
接下来m行,每行3个整数x, y, z,代表城市x和城市y之间有一条耗时为z的双向边。
【输出格式】
对于每组数据输出”Possible”或者”Impossible”.
【样例输入】
2
3 3 11
0 2 7
0 1 6
1 2 5
2 1 10000
1 0 1
【样例输出】
Possible
Impossible
【样例解释】
第一组:0 -> 1 -> 2 :11
第二组:显然偶数时间都是不可能的。
【数据范围】
30%: T <= 10000
另有30%: n <= 5 , m <= 10.
100%: 2 <= n <= 50 , 1 <= m <= 100 , 1 <= z <= 10000 , 1 <= T <= 10^18 , Case <= 5.
暴力dp+骗分40
#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#define maxn 51
#define maxm 20010
#define ll long long
using namespace std;
ll cas,n,m,T,G[maxn][maxn][],f[maxm][maxn];
ll vis[maxn],dis[maxn],diss[maxn],c[maxn];
queue<ll>q;
void Cl(){
memset(G,,sizeof(G));
memset(f,,sizeof(f));
}
void SPFA(){
memset(dis,/,sizeof(dis));
memset(vis,/,sizeof(vis));
while(!q.empty())q.pop();
vis[]=;dis[]=;q.push();
while(!q.empty()){
ll k=q.front();q.pop();
vis[k]=;if(c[k]>n+)break;
for(ll i=;i<=n;i++)
for(ll j=;j<=G[k][i][];j++){
ll v=i,t=G[k][i][j];
if(dis[v]>dis[k]+t){
dis[v]=dis[k]+t;
if(vis[v]==){
q.push(v);vis[v]=;c[v]++;
}
}
}
}
}
void SPFA2(){
memset(diss,/,sizeof(diss));
memset(vis,/,sizeof(vis));
memset(c,,sizeof(c));
while(!q.empty())q.pop();
vis[n]=;diss[n]=;q.push(n);
while(!q.empty()){
ll k=q.front();q.pop();
vis[k]=;if(c[k]>n+)break;
for(ll i=;i<=n;i++)
for(ll j=;j<=G[k][i][];j++){
ll v=i,t=G[k][i][j];
if(diss[v]>dis[k]+t){
diss[v]=dis[k]+t;
if(vis[v]==){
q.push(v);vis[v]=;c[v]++;
}
}
}
}
}
void Solve1(){
f[][]=;
for(ll i=;i<=T;i++)
for(ll j=;j<=n;j++)
for(ll k=;k<=n;k++)
for(ll l=;l<=G[j][k][];l++)
f[i+G[k][j][l]][j]=f[i][k]||f[i+G[k][j][l]][j];
if(f[T][n])printf("Possible\n");
else printf("Impossible\n");
}
void Solve2(){
SPFA();ll falg=;
for(ll i=;i<=n;i++)if(!falg)
for(ll j=;j<=n;j++)if(!falg)
for(ll k=;k<=G[i][j][];k++){
ll x=dis[i],y=diss[j];
if((T-x-y-G[i][j][k])%(G[i][j][k]*)==){
falg=;break;
}
}
if(falg)printf("Possible\n");
else printf("Impossible\n");
}
int main()
{
freopen("travel.in","r",stdin);
freopen("travel.out","w",stdout);
cin>>cas;
while(cas--){
cin>>n>>m>>T;
Cl();ll u,v,t;
for(ll i=;i<=m;i++){
cin>>u>>v>>t;u++;v++;
G[u][v][++G[u][v][]]=t;
G[v][u][++G[v][u][]]=t;
}
if(T<=)Solve1();else Solve2();
}
fclose(stdin);fclose(stdout);
return ;
}
/*
30分的bfs很好想(然而奇葩的我写的dp...跑的好像很慢)
那个状态是 dis[i][j] 1到i 经过时间j 存在不存在
关键是 j 很大 状态会很大 时间会很慢
考虑重复走环的情况 假设 我们从0连出去一个环 大小为x
那么这个环保证了一定能走 如果到 y 时刻能到 n-1 那么y ±x时刻也能到
根据这个性质 我们压缩第三维 %x 意义下
重定义状态dis[i][j]表示 1到 i 走的路程 s s%x为j 且s最小
那么最后的状态 dis[n-1][j] j==T%x 就只0 - n-1 走的路程余数为j的最短路
显然 走T的时间走到n-1的余数和走dis的余数相同 那么就有 dis+kx==T 意思就是
在绕几遍x就好了 因为最后是+kx 所以尽量使dis小 跑最短路
*/
#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
#define maxn 110
#define maxm 50010
#define ll long long
using namespace std;
ll cas,n,m,T,num,head[maxn],mx,dis[maxn][maxm],f[maxn][maxm];
struct edge{
ll v,t,pre;
}e[maxn*];
struct node{
ll x,s;
};
queue<node>q;
void Cl(){
num=;mx=0x7fffffff;
memset(f,,sizeof(f));
memset(head,,sizeof(head));
memset(dis,/,sizeof(dis));
}
void Add(ll from,ll to,ll dis){
num++;e[num].pre=head[from];
e[num].v=to;e[num].t=dis;
head[from]=num;
}
void SPFA(){
dis[][]=;f[][]=;
q.push((node){,});
while(!q.empty()){
ll k=q.front().x;
ll s=q.front().s;
q.pop();f[k][s]=;
for(ll i=head[k];i;i=e[i].pre){
ll v=e[i].v,y=s+e[i].t;y%=mx;
if(dis[v][y]>dis[k][s]+e[i].t){
dis[v][y]=dis[k][s]+e[i].t;
if(f[v][y]==){
f[v][y]=;q.push((node){v,y});
}
}
}
}
}
int main()
{
freopen("travel.in","r",stdin);
freopen("travel.out","w",stdout);
cin>>cas;
while(cas--){
cin>>n>>m>>T;
ll u,v,t;Cl();
for(ll i=;i<=m;i++){
cin>>u>>v>>t;
u++;v++;Add(u,v,t);Add(v,u,t);
if(u==||v==)mx=min(mx,t*);
}
if(mx==0x7fffffff){
printf("Impossible\n");continue;
}
SPFA();
if(dis[n][T%mx]<=T)printf("Possible\n");
else printf("Impossible\n");
}
return ;
}
11.14 noip模拟试题的更多相关文章
- 11.9 noip模拟试题
NOIP2016 模拟赛——那些年,我们学过的文化课背单词(word.c/cpp/pas)[题目描述]fqk 退役后开始补习文化课啦, 于是他打开了英语必修一开始背单词. 看着满篇的单词非常头疼, 而 ...
- 11.13 noip模拟试题
题目名称 笔记 括号 城堡可执行文件名 note brackets castle输入文件名 note.in brackets.in castle.in输出文件名 note.in brackets.ou ...
- 11.12 noip模拟试题
题目名称 加密 冒泡排序图 重建可执行文件名 encrypt bubble rebuild输入文件名 encrypt.in bubble.in rebuild.in输出文件名 encrypt.in b ...
- 11.10 noip模拟试题
1.第K小数 (number.cpp/c/pas) [问题描述] 有两个正整数数列,元素个数分别为N和M.从两个数列中分别任取一个数 相乘,这样一共可以得到N*M个数,询问这N*M个数中第K小数是多少 ...
- 11.7 NOIP模拟赛
目录 2018.11.7 NOIP模拟 A 序列sequence(two pointers) B 锁lock(思路) C 正方形square(埃氏筛) 考试代码 B C 2018.11.7 NOIP模 ...
- 11/1 NOIP 模拟赛
11.1 NOIP 模拟赛 期望得分:50:实际得分:50: 思路:暴力枚举 + 快速幂 #include <algorithm> #include <cstring> #in ...
- 10.11 noip模拟试题
4题均为128M,1s 1. 锻炼计划(exercise.pas) 身体是革命的本钱,OIers不要因为紧张的学习和整天在电脑前而忽视了健康问题.小x设计了自己的锻炼计划,但他不知道这个计划是否可行, ...
- 10.4 noip模拟试题
题目名称 PA 青春 三部曲 名称 huakai taritari truetears 输入 huakai.in taritari.in truetears.in 输出 huakai.out tari ...
- 9.26 noip模拟试题
魔术球问题弱化版(ball.c/.cpp/.pas) 题目描述 假设有 n 根柱子,现要按下述规则在这 n 根柱子中依次放入编号为 1,2,3,…的球. (1)每次只能在某根柱子的最上面放球. (2) ...
随机推荐
- bzoj2281
有思维难度的好题这种题我们一般可以先从部分分考虑30%的分数k=2也就是黑白各一个不难发现如果初始黑白棋子相邻那必然是先手必败态否则一定是先手必胜那么30分的部分分是很容易拿到的,组合数学如果有多个棋 ...
- Webform和MVC,为什么MVC更好一些?
前言 如果你看了最近微软的议程,你会发现他们现在的焦点除了MVC,还是MVC.问题在于为什么微软如此热衷于丢弃传统的APS.NET Webform而转向ASP.NET MVC?本文就主要来讨论这个问题 ...
- 文件写操作--WriteLog
private static void Write(string sMsg, string fileName) { if (sMsg != "") { try { var dir ...
- CefSharp中实现Chrome中jS导出Excel
[前言] 在博客园闲逛了一年多,平时都是借鉴别人的成功经验,总觉得自己应该分享点什么,但是苦于自己技术有限,平时又不爱写东西,所以一直没有写过任何东西.毕业一年多,在现实工作中遇到各种问题,深切体会到 ...
- Linux SCP 命令: 利用SSH传输文件
在linux下一般用scp这个命令来通过ssh传输文件. 1.从服务器上下载文件scp username@servername:/path/filename /var/www/local_dir(本地 ...
- 【CSS】Intermediate5:Specificity
1.More Specific=Greater Precedence =>nested selectors 2. the selectors are the same then the last ...
- (4)I2C总线的7bit从机地址
时钟拉伸(Clock stretching)clock stretching通过将SCL线拉低来暂停一个传输.直到释放SCL线为高电平,传输才继续进行.clock stretching是可选的,实际上 ...
- oracle rac 学习(转载)
一. RAC 并发 RAC 的本质是一个数据库,运行在多台计算机上的数据库,它的主要任务是数据库就是事务处理,它通过 Distributed Lock Management(DLM:分布式锁管理器) ...
- IIS ASP.NETWEB站点部署时遇到的问题记录
最近由于工作的需要,需要自己部署一些ASP.NET站点,但中间出现了一点小小的问题. 由于自己才疏学浅,此问题折腾了我将近一个小时,最后还是百度出了解决这个问题的方法,先记录如下,仅供自己记忆用. 我 ...
- 页面置换算法(最佳置换算法、FIFO置换算法、LRU置换算法、LFU置换算法)
页面置换产生的原因是:分页请求式存储管理(它是实现虚拟存储管理的方法之一,其中一个特性是多次性-->多次将页面换入或换出内存) 效果最好的页面置换算法:最佳置换算法 比较常用的页面置换算法有:F ...