传送门

考查题型 二分图 暴力枚举 判断素数 dp

T1

传纸条

题目描述

小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题。一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了。幸运的是,他们可以通过传纸条来进行交流。纸条要经由许多同学传到对方手里,小渊坐在矩阵的左上角,坐标(1,1),小轩坐在矩阵的右下角,坐标(m,n)。从小渊传到小轩的纸条只可以向下或者向右传递,从小轩传给小渊的纸条只可以向上或者向左传递。

在活动进行中,小渊希望给小轩传递一张纸条,同时希望小轩给他回复。班里每个同学都可以帮他们传递,但只会帮他们一次,也就是说如果此人在小渊递给小轩纸条的时候帮忙,那么在小轩递给小渊的时候就不会再帮忙。反之亦然。

还有一件事情需要注意,全班每个同学愿意帮忙的好感度有高有低(注意:小渊和小轩的好心程度没有定义,输入时用0表示),可以用一个0-100的自然数来表示,数越大表示越好心。小渊和小轩希望尽可能找好心程度高的同学来帮忙传纸条,即找到来回两条传递路径,使得这两条路径上同学的好心程度只和最大。现在,请你帮助小渊和小轩找到这样的两条路径。

输入输出格式

输入格式:

输入文件message.in的第一行有2个用空格隔开的整数m和n,表示班里有m行n列(1<=m,n<=50)。

接下来的m行是一个m*n的矩阵,矩阵中第i行j列的整数表示坐在第i行j列的学生的好心程度。每行的n个整数之间用空格隔开。

输出格式:

输出文件message.out共一行,包含一个整数,表示来回两条路上参与传递纸条的学生的好心程度之和的最大值。

输入输出样例

输入样例#1:

3 3
0 3 9
2 8 5
5 7 0
输出样例#1:

34

说明

【限制】

30%的数据满足:1<=m,n<=10

100%的数据满足:1<=m,n<=50

NOIP 2008提高组第三题

题解

原以为是从起点bfs出一条最短路和一条次短路

结果发现最短路把次短路堵住了 没法找次短路了。

题解是双线程dp 涨姿势

代码

#include<iostream>
#include<cstdio>
using namespace std;
int n,m,loe[][],f[][][][];
int main(){
scanf("%d%d",&m,&n);
for(int i=;i<=m;i++){
for(int j=;j<=n;j++){
scanf("%d",&loe[i][j]);
}
}
for(int a=;a<=m;a++){
for(int b=;b<=n;b++){
for(int c=;c<=m;c++){
for(int d=;d<=n;d++){
int t=max(f[a][b-][c][d-],f[a][b-][c-][d]);
int z=max(f[a-][b][c][d-],f[a-][b][c-][d]);
f[a][b][c][d]=max(t,z)+loe[a][b]+loe[c][d];
if(a==c&&b==d)f[a][b][c][d]-=loe[a][b];
}
}
}
}
printf("%d\n",f[m][n][m][n]);
return ;
}

T2

笨小猴

题目描述

笨小猴的词汇量很小,所以每次做英语选择题的时候都很头疼。但是他找到了一种方法,经试验证明,用这种方法去选择选项的时候选对的几率非常大!

这种方法的具体描述如下:假设maxn是单词中出现次数最多的字母的出现次数,minn是单词中出现次数最少的字母的出现次数,如果maxn-minn是一个质数,那么笨小猴就认为这是个Lucky Word,这样的单词很可能就是正确的答案。

输入输出格式

输入格式:

输入文件word.in只有一行,是一个单词,其中只可能出现小写字母,并且长度小于100。

输出格式:

输出文件word.out共两行,第一行是一个字符串,假设输入的的单词是Lucky Word,那么输出“Lucky Word”,否则输出“No Answer”;

第二行是一个整数,如果输入单词是Lucky Word,输出maxn-minn的值,否则输出0。

输入输出样例

输入样例#1:

error
输出样例#1:

Lucky Word
2
输入样例#2:

olympic
输出样例#2:

No Answer
0

说明

【输入输出样例1解释】

单词error中出现最多的字母r出现了3次,出现次数最少的字母出现了1次,3-1=2,2是质数。

【输入输出样例2解释】

单词olympic中出现最多的字母i出现了2次,出现次数最少的字母出现了1次,2-1=1,1不是质数。

//注:此处原题解释有误,实际上是0,也不是质数。

noip2008提高第一题

题解

判断素数

代码

//特别判断1既不是素数也不是合数,tm还有个0,统计完之后找最大最小值
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
string str;
int q[];
int len,maxn=-,minn=;
bool pd(int x){
if(x==)return ;
if(x==)return ;
//if(x<=3)return 1;
for(int i=;i*i<=x;i++)
if(x%i==)return ;
return ;
}
int main(){
cin>>str;len=str.length();
for(int i=;i<len;i++){q[str[i]-'a']++;}
for(int i=;i<len;i++){
if(q[str[i]-'a']>maxn)maxn=q[str[i]-'a'];
if(q[str[i]-'a']<minn)minn=q[str[i]-'a'];
}
// cout<<maxn<<" "<<minn<<endl;
if(pd(maxn-minn)){printf("Lucky Word\n%d\n",maxn-minn);}
else {printf("No Answer\n0\n");}
}

T3

火柴棒等式

题目描述

给你n根火柴棍,你可以拼出多少个形如“A+B=C”的等式?等式中的A、B、C是用火柴棍拼出的整数(若该数非零,则最高位不能是0)。用火柴棍拼数字0-9的拼法如图所示:

注意:

  1. 加号与等号各自需要两根火柴棍

  2. 如果A≠B,则A+B=C与B+A=C视为不同的等式(A、B、C>=0)

  3. n根火柴棍必须全部用上

输入输出格式

输入格式:

输入文件matches.in共一行,又一个整数n(n<=24)。

输出格式:

输出文件matches.out共一行,表示能拼成的不同等式的数目。

输入输出样例

输入样例#1:

样例输入1:
14
样例输入2:
18
输出样例#1:

样例输出1:
2
样例输出2:
9

说明

【输入输出样例1解释】

2个等式为0+1=1和1+0=1。

【输入输出样例2解释】

9个等式为:

0+4=4
0+11=11
1+10=11
2+2=4
2+7=9
4+0=4
7+2=9
10+1=11
11+0=11
题解 暴力枚举
代码
//妈的以后写个mul函数 我还要一个一个算 代码丑还写错kao
#include<iostream>
#include<cstdio>
using namespace std;
int n,ans;
int a[]={,,,,,,,,,};
int mul(int s){
if(s<=)return a[s];
int t=;
while(s){t+=a[s%];s/=;}
return t;
}
int main(){
scanf("%d",&n);n-=;int x;
// while(scanf("%d",&x))cout<<mul(x)<<endl;
for(int i=;i<=;i++){
for(int j=;j<=;j++){
if(mul(i)+mul(j)+mul(i+j)==n)ans++;
}
}
printf("%d\n",ans);
return ;
}

T4

双栈排序

题目描述

Tom最近在研究一个有趣的排序问题。如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序。

操作a

如果输入序列不为空,将第一个元素压入栈S1

操作b

如果栈S1不为空,将S1栈顶元素弹出至输出序列

操作c

如果输入序列不为空,将第一个元素压入栈S2

操作d

如果栈S2不为空,将S2栈顶元素弹出至输出序列

如果一个1~n的排列P可以通过一系列操作使得输出序列为1,2,…,(n-1),n,Tom就称P是一个“可双栈排序排列”。例如(1,3,2,4)就是一个“可双栈排序序列”,而(2,3,4,1)不是。下图描述了一个将(1,3,2,4)排序的操作序列:<a,c,c,b,a,d,d,b>

当然,这样的操作序列有可能有几个,对于上例(1,3,2,4),<a,c,c,b,a,d,d,b>是另外一个可行的操作序列。Tom希望知道其中字典序最小的操作序列是什么。

输入输出格式

输入格式:

输入文件twostack.in的第一行是一个整数n。

第二行有n个用空格隔开的正整数,构成一个1~n的排列。

输出格式:

输出文件twostack.out共一行,如果输入的排列不是“可双栈排序排列”,输出数字0;否则输出字典序最小的操作序列,每两个操作之间用空格隔开,行尾没有空格。

输入输出样例

输入样例#1:

【输入样例1】
4
1 3 2 4
【输入样例2】
4
2 3 4 1
【输入样例3】
3
2 3 1
输出样例#1:

【输出样例1】
a b a a b b a b
【输出样例2】
0
【输出样例3】
a c a b b d

说明

30%的数据满足: n<=10

50%的数据满足: n<=50

100%的数据满足: n<=1000

题解

首先找出不能放在同一个栈里的元素

条件 j<i<k时(i,j,k为下标,即序列第几个数)当 a[i]>a[j]>a[k]时i,j不能放到一个栈。

i--j连边。然后二分图染色,能二分就说明能双栈排序,最后贪心模拟输出

代码

//用stl取出元素时一定要判断空不空
#include<iostream>
#include<algorithm>
#include<stack>
#include<queue>
#include<cstring>
#include<cstdio>
using namespace std;
int head[],a[],col[],f[],staca[],stacb[];
int sumedge,n,topa,topb,flag;
queue<int>q;
stack<int>p[];
struct Edge{
int x,y,nxt;
Edge(int x=,int y=,int nxt=):
x(x),y(y),nxt(nxt){}
}edge[];
void add(int x,int y){
edge[++sumedge]=Edge(x,y,head[x]);
head[x]=sumedge;
}
void color(int s){
q.push(s);
while(q.size()){
int now=q.front();q.pop();
for(int i=head[now];i;i=edge[i].nxt){
int v=edge[i].y;
if(col[v]==-)col[v]=col[now]^,q.push(v);
else {
if(col[v]==col[now]){
printf("0\n");exit();
}
}
}
}
}
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++)scanf("%d",&a[i]);
f[n+]=;
for(int i=n;i>=;i--)f[i]=min(f[i+],a[i]);
for(int i=;i<=n;i++){
for(int j=i+;j<=n;j++){
if(a[j]>a[i]&&a[i]>f[j+])add(i,j),add(j,i);
}
}
memset(col,-,sizeof(col));
for(int i=;i<=n;i++){
if(col[i]==-){col[i]=;color(i);}
}
/* for(int i=1;i<=n;i++){
if(col[i]==1){
if(a[i]>staca[topa]&&topa){
topa--;printf("b ");continue;
}else {staca[++topa]=a[i];printf("a ");continue;}
}
if(col[i]==0){
if(a[i]>stacb[topb]&&topb){
topb--;printf("d ");continue;
}else{stacb[++topb]=a[i];printf("c ");continue;}
}
}
if(topa||topb){
if(staca[topa]>stacb[topb]){
while(topa)printf("b "),topa--;
while(topb)printf("d "),topb--;
}else{while(topb)printf("d "),topb--;
while(topa)printf("b "),topa--;
}
}*/
int now=,T=;
while(){
if(now>n)break;
if(col[T]==&&(p[].empty()||p[].top()>a[T])){
p[].push(a[T]);T++;printf("a ");
continue;
}
if(!p[].empty()&&p[].top()==now){
p[].pop();now++;printf("b ");
continue;
}
if(col[T]==&&(p[].empty()||p[].top()>a[T])){
p[].push(a[T]);T++;printf("c ");
continue;
}
if(!p[].empty()&&p[].top()==now){
p[].pop();now++;printf("d ");
continue;
}
}
return ;
}

最新文章

  1. python之模块
  2. 安装composer
  3. yum命令安装mysql
  4. 17. Word Break &amp;&amp; Word Break II
  5. BZOJ4320 : ShangHai2006 Homework
  6. python: html
  7. apache开源项目 -- tajo
  8. 在微信小程序的JS脚本中使用Promise来优化函数处理
  9. 快速开发 HTML5 WebGL 的 3D 斜面拖拽生成模型
  10. 自编译Apache Spark2.3.3支持CDH5.16.1
  11. max-width和width的区别
  12. 【WebApi系列】浅谈HTTP在WebApi开发中的运用
  13. [NOIP2018]OI之旅的中转站
  14. 一、Redis的学习
  15. 针对SO交期回写的工厂日历功能调整
  16. .net中的SelectList在Html.DropdownList中的使用
  17. 从游戏开发到web前端——仅仅只是开始
  18. windows下Nginx反向代理服务器安装与配置
  19. Java中取两位小数
  20. jdk与jdt

热门文章

  1. Struts2防止重复提交
  2. 快速掌握RabbitMQ(二)——四种Exchange介绍及代码演示
  3. 关于css虚线
  4. raspi集成库及安装
  5. 洛谷P1352 没有上司的舞会
  6. Windows下使用Nexus搭建Maven私服(使用)
  7. send to instance already dealloc nil error
  8. 基于MNIST数据的softmax regression
  9. UVa 10295 - Hay Points
  10. jQuery Ajax Post Data Example