\(\\\)

\(\#A\) \(Word\)


给出一个长为\(N\)的小写字母串,判断出现所有字母中最多出现次数减最少出现次数得到的答案是否是质数。

  • \(N\in [1,100]\)
  • 直接按题意开桶记录,试除法判断即可。
#include<cmath>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 30
#define M 110
#define R register
using namespace std;bool v1[N],v2[N];
int to[N],now[M],p;int main(){char c=getchar();while(!isupper(c)) c=getchar();while(isupper(c)){now[++now[0]]=c-'A'+1;v1[c-'A'+1]=1; c=getchar();}for(R int i=1;i<=26;++i) if(!v1[i]){puts("Failed");return 0;}while(!isupper(c)) c=getchar();while(isupper(c)){int x=now[++p];if(to[x]){if('A'+to[x]-1!=c){puts("Failed");return 0;}}else if(v2[c-'A'+1]){puts("Failed");return 0;}else to[x]=c-'A'+1;v2[c-'A'+1]=1; c=getchar();}while(!isupper(c)) c=getchar();while(isupper(c)){putchar((char)'A'+to[c-'A'+1]-1);c=getchar();}return 0;
}

\(\\\)

\(\#B\) \(Matches\)


已知用火柴棒拼出每个数字所需要的数量,加号和等号各需要两根,求恰好用掉\(N\)根火柴棒构成等式\(A+B=C\)的数量,其中数字不能有前导零,当\(A\not=B\)时交换位置视作两个等式。

  • \(N\in [0,24]\)
  • 用暴力跑一跑,发现最大的数据范围能做到的等式数字大小不会超过\(1000\)。
  • 于是预处理前\(1000\)个数每个数所需个数,\(N^2\)暴力枚举判断即可。
#include<cmath>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define R register
using namespace std;const int cost[10]={6,2,5,5,4,5,6,3,7,6};int n,cnt,f[2500]={6};inline void calc(int x){int tmp=x,res=0;while(tmp){res+=cost[tmp%10];tmp/=10;}f[x]=res;
}int main(){scanf("%d",&n); n-=4;for(R int i=1;i<=2300;++i) calc(i);for(R int i=0;i<=1111;++i)for(R int j=0;j<=1111;++j)if(f[i]+f[j]+f[i+j]==n) ++cnt;printf("%d\n",cnt);return 0;
}

\(\\\)

\(\#C\) \(Massage\)


给出一个\(N\times M\)的矩阵,选则两条从\((1,1)\)到\((N,M)\)的路径,使得两条路径上的权值和最大,注意每个格点的权值只能被计入答案一次。

  • \(N,M\in [0,50]\)
  • 状态显然跟步数以及两条路径的当前终点\((x_1,y_1)(x_2,y_2)\)有关,注意到两个终点的横纵坐标之和是固定的,因为起点为\((1,1)\),所以有\(x_1+y_1=x_2+y_2=2+\)当前步数。

  • 精简状态,设\(f[i][j][k]\)表示当前两节点横纵坐标之和(即\(2+\)当前步数)为\(i\),第一条路径终点为\((j,i-j)\),第二条路径终点为\((k,i-k)\)的最大路径权值和。有显然的初始化\(f[2][1][1]=val[1][1]\)。

  • 考虑对于已知状态\(f[i][j][k]\)的转移,根据下一步两条路径的行动方向讨论,有\(2\times 2=4\)种情况:

    • 两个都向下:若当前两终点重合,则下一步也重合,权值只计算一次,否则分开累加答案:
    if(j==k) f[i+1][j+1][k+1]=max(f[i+1][j+1][k+1],f[i][j][k]+val[j+1][i-j]);
    else f[i+1][j+1][k+1]=max(f[i+1][j+1][k+1],f[i][j][k]+val[j+1][i-j]+val[k+1][i-k]);
    • 两个都向右:讨论同上:
    if(j==k) f[i+1][j][k]=max(f[i+1][j][k],f[i][j][k]+val[j][i+1-j]);
    else f[i+1][j][k]=max(f[i+1][j][k],f[i][j][k]+val[j][i+1-j]+val[k][i+1-k]);
    • 第一个向右,第二个向下:若\(j=k+1\),则代表下一步重合,权值只计算一次,否则分开累加:
    if(k==j-1) f[i+1][j][k+1]=max(f[i+1][j][k+1],f[i][j][k]+val[j][i+1-j]);
    else f[i+1][j][k+1]=max(f[i+1][j][k+1],f[i][j][k]+val[j][i+1-j]+val[k+1][i-k]);
    • 第一个向下,第二个向右:讨论同上,条件改为\(k=j+1\):
    if(j==k-1) f[i+1][j+1][k]=max(f[i+1][j+1][k],f[i][j][k]+val[k][i+1-k]);
    else f[i+1][j+1][k]=max(f[i+1][j+1][k],f[i][j][k]+val[k][i+1-k]+val[j+1][i-j]);
  • 答案即为\(f[N+M][N][N]\)。

#include<cmath>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 120
#define R register
#define gc getchar
using namespace std;int n,m,val[N][N],f[N<<1][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(){n=rd(); m=rd();for(R int i=1;i<=n;++i)for(R int j=1;j<=m;++j) val[i][j]=rd();f[2][1][1]=val[1][1];for(R int i=2;i<=n+m-1;++i)for(R int j=1;j<=n;++j)for(R int k=1;k<=n;++k){if(j==k){f[i+1][j][k]=max(f[i+1][j][k],f[i][j][k]+val[j][i+1-j]);f[i+1][j+1][k+1]=max(f[i+1][j+1][k+1],f[i][j][k]+val[j+1][i-j]);}else{f[i+1][j][k]=max(f[i+1][j][k],f[i][j][k]+val[j][i+1-j]+val[k][i+1-k]);f[i+1][j+1][k+1]=max(f[i+1][j+1][k+1],f[i][j][k]+val[j+1][i-j]+val[k+1][i-k]);}if(j==k-1) f[i+1][j+1][k]=max(f[i+1][j+1][k],f[i][j][k]+val[k][i+1-k]);else f[i+1][j+1][k]=max(f[i+1][j+1][k],f[i][j][k]+val[k][i+1-k]+val[j+1][i-j]);if(k==j-1) f[i+1][j][k+1]=max(f[i+1][j][k+1],f[i][j][k]+val[j][i+1-j]);else f[i+1][j][k+1]=max(f[i+1][j][k+1],f[i][j][k]+val[j][i+1-j]+val[k+1][i-k]);}printf("%d\n",f[n+m][n][n]);return 0;
}

\(\\\)

\(\#D\) \(Twostack\)


试通过\(2\)个栈\(S_1\)和\(S_2\),借助以下\(4\)种操作实现将输入的一个\(N\)的排列升序排序。

  • 操作\(a\):如果输入序列不为空,将第一个元素压入栈\(S_1\)
  • 操作\(b\):如果栈\(S_1\)不为空,将\(S_1\)栈顶元素弹出至输出序列
  • 操作\(c\):如果输入序列不为空,将第一个元素压入栈\(S_2\)
  • 操作\(d\):如果栈\(S_2\)不为空,将\(S_2\)栈顶元素弹出至输出序列

如果输入的排列不是“可双栈排序排列”,输出\(0\)。否则输出字典序最小的操作序列。

  • \(N\in [0,1000]\)
  • 当两个数不能连续进入同一个栈,首先需要满足前面的数小于后面的数,其次,前面的数不能在后面的数进栈之前弹出。当一个数可以弹栈,证明小于它的数字已经全部弹出,所以我们可以这样判断:

    • 预处理出每一个数的后缀\(min\)。
    • \(N^2\)枚举两个数\(a,b\)(\(a\)在\(b\)之前出现):若\(a<b\)且\(a>min_b\)则证明两者不能进入同一个栈。
  • 如何判断是否有合法操作序列呢?注意到若合法这些点应该能通过互斥关系至多分成两类,所以不妨在不能进入同一个栈的两个点间连边,进行二分图染色,若该图是二分图则证明有合法操作关系。
  • 因为要最小字典序答案,所以第一个数必定进\(S_1\)栈,注意到可能这张图不连通,所以将每次第一个遇到的点都染成黑色,代表进入\(S_1\)栈。
  • 然后就可以模拟进出栈的过程了:每到一个点就按照染色入栈,然后检查是否有需要弹栈的数字,因为我们确定了输入序列为一个排列,所以直接通过栈顶权值判断。
  • 但注意不能直接在插入之后把所有能弹出的数字都弹出,因为可能会存在先让数字进入第一个栈再弹出第二个栈的更优解法,所以操作变为:若插入\(S_2\),则能弹则弹;若插入\(S_1\),则先将一号栈该弹出的弹出(注意可能会附加二号栈的弹出),入栈,再将二号栈该弹出的弹出。
#include<cmath>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 1010
#define R register
#define gc getchar
#define top1 stk1[0]
#define top2 stk2[0]
using namespace std;int num[N],mn[N],to[N],stk1[N],stk2[N];int n,m,tot,hd[N];
struct edge{int to,nxt;}e[N*N];
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 bool dfs(int u,int tmp){to[u]=tmp;for(R int i=hd[u],v;i;i=e[i].nxt)if(!to[v=e[i].to]){if(dfs(v,3-tmp))return 1;}else if(to[v]==tmp) return 1;return 0;
}int main(){n=rd();for(R int i=1;i<=n;++i) num[i]=rd();mn[n]=num[n];for(R int i=n-1;i>=1;--i) mn[i]=min(mn[i+1],num[i]);for(R int i=1;i<n;++i)for(R int j=i+1;j<=n;++j)if(num[i]<num[j]&&num[i]>mn[j]){add(i,j);add(j,i);}for(R int i=1;i<=n;++i)if(!to[i]) if(dfs(i,1)){putchar('0');return 0;};m=1;for(R int i=1;i<=n;++i){if(to[i]==1){putchar('a'); putchar(' '); stk1[++top1]=num[i];}else{putchar('c'); putchar(' '); stk2[++top2]=num[i];}while(stk1[top1]==m||stk2[top2]==m){if(stk1[top1]==m){putchar('b');putchar(' ');--top1;}else{putchar('d');putchar(' ');--top2;} ++m;}}return 0;
}

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

[ NOIP 2008 ] TG相关推荐

  1. NOIP 2008 提高组 复赛 message 传字条

    NOIP 2008 提高组 复赛 message 传字条 1.样例很快模拟成功,但感觉是凑出来的,没有章法. 2.深度优先遍历,但感觉容易超时. 3.动态规划?翻看他人代码,发现动态规划的写法,确实想 ...

  2. NOIP 2008 普及组初赛试题 解题报告、题解及选择题思路,高质量

    做题:https://ti.luogu.com.cn/problemset/1003 选择题 第 1 题 微型计算机中,控制器的基本功能是( A). A. 控制机器各个部件协调工作 B. 实现算术运算 ...

  3. [ NOIP 2014 ] TG

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

  4. noip pj,tg酱油记

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

  5. [ NOIP 1998 ] TG

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

  6. [Luogu P3960] [UOJ 334] [NOIP 2017 tg]列队

    洛谷传送门 UOJ传送门 题目描述 Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有n×mn \time ...

  7. NOIP 2008 普及组 传球游戏

    超时,满足40%的数据 #include <bits/stdc++.h> using namespace std;int n, m, ans;//第cnt次传球后,球在编号为x的同学手上 ...

  8. NOIP 2008 传球游戏

    这道题呢,我用了一下搜索,还用了一下dp 搜索是40PAC,dp是稳过的 然后呢遇到边缘值我都进行了特殊判断,我感觉这么写好写点 先来看看搜索 #include<bits/stdc++.h> ...

  9. NOIp系列题目及CF小结

    长期更新中2333 2018/7/2 先看一下昨晚的cf Codeforces Round #493 (Div. 2) A. Balloons 这个题...直接模拟233 B. Cutting 来一下 ...

最新文章

  1. Eclipse下git如何创建分支
  2. 3_3 ObserverMode 观察者模式
  3. 《Effective Java》—— 对于所有对象都通用的方法
  4. EF连接ORACLE
  5. matlab自带四旋翼算例asbQuadcopter使用心得
  6. python付费课程推荐知乎_新手小白学习Python,有什么课程推荐吗?
  7. 程序员的身价取决于手中产品
  8. vue引用jquery
  9. 易科软件中国:维系客户关系是企业的根本
  10. 简单类型参数是值传递,对象参数是引用传递
  11. “微音乐”微信小程序实战开发过程
  12. JAVA实现EXCEL公式专题(七)——统计函数
  13. 360浏览器极速模式和兼容模式
  14. 在 Pixel 3 手机上学习预测深度
  15. gimp 抠图_【GIMP学习】抠图方法二则
  16. Excel精选28个实用技巧实例学习
  17. python学习-循环替换txt文件中的指定字符
  18. redis为什么采用跳表而不是红黑树详解
  19. 【LeetCode】322. 零钱兑换 结题报告 (C++)
  20. QQ邮箱取消免费扩容;苹果搜索引擎“胎死腹中”,核心成员已回归谷歌麾下;Xcode 14导致应用体积大增|极客头条

热门文章

  1. FusionCharts下载地址汇总及更新介绍
  2. C# 小数位数保留的方法集锦
  3. Delphi的彩蛋 (好像Delphi5~Delphi7都可以)
  4. O(n^2) 级别的排序算法
  5. java调用c库实例
  6. 数组、哈希以及其他枚举类型
  7. 《Adobe Flash Professional CC经典教程》——1.3 使用“库”面板
  8. 以比特币现金(BCH)为核心的慈善经济体系革新业态
  9. Android 录音功能直接拿去用
  10. 安装numpy/scipy/scikit-learn的方法