题目链接:https://ac.nowcoder.com/acm/contest/90#question
A.跳台阶
链接:https://ac.nowcoder.com/acm/contest/90/A
来源:牛客网
题目描述
有一个n级台阶的楼梯,小明一次可以向上跳1步,两步,甚至是n步,请问小明跳到n级台阶有多少种跳法?
输入描述:
第一行输入一个整数t,代表有t组样例:( T<=30)
接下来的t行,都用一个整数n,表示楼梯有n级台阶( 1<=n<=30)
输出描述:
输出跳到第n级台阶有多少种跳法
示例1
输入
复制
1
1
输出
复制
1
有2种做法,第一种暴力dp,dp[i]+=dp[j],j为1~i-1复杂度O(n^2),第二种推公式dp[i]=2*dp[i-1]
f(n) = f(n-1)+f(n-2)+f(n-3)+......+f(n-n)=f(0)+f(1)+f(2)+......+f(n-1)
又因为f(n-1)=f(0)+f(1)+f(2)+.......+f(n-2)
两式相减得:f(n)-f(n-1)=f(n-1)得到 Fib(n) = 2*Fib(n-1) (n >= 2)
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int main(){
long long dp[35];
int T,n;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
memset(dp,0,sizeof(dp));
dp[1]=1;
for(int i=2;i<=n;i++)
dp[i]=2*dp[i-1];
// for(int i=1;i<=n;i++)
// for(int j=0;j<i;j++)
// dp[i]+=dp[j];
printf("%lld\n",dp[n]);
}
return 0;
}
B.跳一跳,很简单的
链接:https://ac.nowcoder.com/acm/contest/90/B
来源:牛客网
题目描述
有一无限循环字母表:
现在有一棵n个节点(编号1-n)的有根树(1为根),树边边权为一个字母θ,在每一时刻θ会向前跳K步变为相应字母(即树边边权改变),如:
n每一时刻会向前跳3步,第1时刻变为q,第2时刻变为t,以此类推。
w每一时刻会向前跳2步,第1时刻变为y,第2时刻变为a,以此类推。
JK会给你Q个询问,让你判断两个节点在t时刻到根节点路径权值(路径权值为该节点到根节点的路径上字母按顺序拼成的字符串)的字典序大小关系。
输入描述:
第一行一个整数T(0<T<3),代表测试数据组数。
每一组测试数据第一行给出树的节点数n(1<n<=100000)。
接下去的n-1行的第i行给出一个整数P(1<=P<=n),一个字母θ([a-z])以及字母变换的步数K(0<=K<=10000),表示编号为i+1的节点的父亲节点编号为P,以及边的描述。(输入保证为一棵树)
下一行询问数Q(0<Q<=10000),每个询问一行给出整数u(2<=u<=n),v(2<=v<=n),t(0<=t<=10000),判断编号为u,v两个节点在t时刻到根节点路径权值的字典序大小关系。
输出描述:
对每个询问输出一行答案,
编号u到根节点路径权值的字典序小于v的输出“<”,
相等输出“=”,
否则输出“>”。(不包含该引号)
示例1
输入
复制
1
10
1 a 1
1 a 5
1 c 2
2 f 2
3 a 5
3 e 3
4 b 1
5 z 1
7 o 2
4
5 7 0
5 7 2
9 10 1
8 8 8
输出
复制
>
<
<
=
通过率低,有空去补
C.平分游戏
链接:https://ac.nowcoder.com/acm/contest/90/C
来源:牛客网
题目描述
集训队一共有n位同学,他们都按照编号顺序坐在一个圆桌旁。第i位同学一开始有a[i]个硬币,他们希望使得每位同学手上的硬币变成相同的数目。每一秒钟,有且仅有一位同学可以把自己手上的一枚硬币交给另一位同学,其中这两位同学中间必须间隔k位同学。
现在问的是最少几秒后所有同学手上的有相同数量的硬币
输入描述:
第一行输入两个整数n,k(1<=n<=1000000,0<=k<=n)
接下来的一行有n个整数,第i个整数a[i](0<=a[i]<=1e9)表示第i位同学手上的硬币的数量。
输出描述:
一个整数,表示最少几秒后所有同学手上的有相同数量的硬币。如果不可能,则输出gg。
示例1
输入
复制
5 0
2 3 1 5 4
输出
复制
3
D.psd面试
链接:https://ac.nowcoder.com/acm/contest/90/D
来源:牛客网
题目描述
然而面试官 xwc 一眼就看到了重点:大学打过 ACM!
xwc:“
听说你很低袄?考你个题:
忽略字母大小写,你这篇简历去掉最长的回文子序列后还有多长?
”
psd 顺手就把这个问题抛给了你。
输入描述:
多组输入,每组输入一个长度不超过 1234 的没空格的字符串,是 psd 的简历。
输出描述:
每组输出一个整数,如题。
示例1
输入
复制
google
输出
复制
2
示例2
输入
复制
aBc,bAd
输出
复制
2
题目废话很多,适当删减
区间dp,LIS最长公共子序列变形
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int dp[2005][2005];
int main(){
string s;
while(cin>>s){
int n = s.size(),j,k;
transform(s.begin(),s.end(),s.begin(),::tolower);
for(int i=0;i<n;i++)
dp[i][i] = 1;
for(int len=2;len<=n;len++)
for(int i=0;i<n-len+1;i++){
int j = i+len-1;
if(s[i]==s[j])
dp[i][j] = 2 + dp[i+1][j-1];
else
dp[i][j] = max(dp[i+1][j],dp[i][j-1]);
}
cout<<n-dp[0][n-1]<<endl;
}
return 0;
}
E.回旋星空
链接:https://ac.nowcoder.com/acm/contest/90/E
来源:牛客网
题目描述
曾经有两个来自吉尔尼斯的人(A和C)恋爱了,他们晚上经常在一起看头上的那片名为假的回旋星空,
有一天他们分手了,A想通过回旋星空测量他们之间的复合指数,测量的规则是,
计算回旋图标的个数,即选中三颗星星,分别作为回旋图标的起点,拐点和终点,假设现在有三个
星星分别为i,j,k,如果d(a[i],a[j]) == d(a[j],a[k])则表示找到了一个回旋图标,其中d(x,y)表示这两个点的欧氏距离
为了给它很大的希望(i,j,k)和(k,j,i)被认为是两个不同的回旋图标
A花了一晚上终于把整片星空映射到了一张二平面图上,由于星星太多以至于A有点懵逼,所以
你能帮帮他吗,要不然他可能真的WA的一声哭了出来
作为埃森哲公司的一员,你在解决问题的同时也向A介绍了埃森哲公司的业务范围。
为了全方位地满足客户的需求,正在不断拓展自身的业务服务网络,包括管理及信息技术咨询、企业经营外包、企业联盟和风险投资。除了以产品制造业、通信和高科技、金融服务、资源、政府机构等不同行业划分服务内容之外,还从以下几方面提供咨询服务:
1.客户关系管理
2.业务解决方案
3.电子商务
4.供应链管理
输入描述:
第一行一个整数T(T<=10),表示组数
对于每组数据有一个n,表示有n个小星星(0< n < 1000)
接下来跟着n行,每行跟两个整数xi和yi表示每个星星的坐标(-10000< xi, yi<10000)
输出描述:
对于每组数据,如果没有找到回旋图标输出”WA”,否则输出找到图标个数
示例1
输入
复制
2
2
1 0
0 1
3
1 0
0 1
0 0
输出
复制
WA
2
备注:
没有重复的星星,且选中的三个星星是互相不一样的(即下标不同)
欧氏距离即直线距离
思维,排列组合,几何
从暴力枚举每3个点转化为枚举每2个边,降低了复杂度,从O(n^3)->O(n^2)
每一次计算有多少种组合时,必须是在第一个for内结算,这样才能保证每2个边是相邻的,最后因为每2边交换也算一种方案,所以用A(n,2),而不用C(n,2),当然最后乘2也是可以的,比如有3个相同的边,公式就是3*2=6,把所以的这种方案数累加即可
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long ll;
int x[1005],y[1005];
int T,n;
int main(){
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d%d",&x[i],&y[i]);
ll ans=0;
for(int i=0;i<n;i++){
vector<int> dis;
for(int j=0;j<n;j++)
if(i!=j)
dis.push_back((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
sort(dis.begin(),dis.end());
for(int l=0,r=0;l<dis.size();l=r){
while(r<dis.size() && dis[l]==dis[r])
r++;
ans+=(r-l)*(r-l-1);//排列A n 2
}
}
if(ans==0)
printf("WA\n");
else
printf("%lld\n",ans);
}
return 0;
}
F.等式
链接:https://ac.nowcoder.com/acm/contest/90/F
来源:牛客网
题目描述
给定n,求1/x + 1/y = 1/n (x<=y)的解数。(x、y、n均为正整数)
输入描述:
在第一行输入一个正整数T。
接下来有T行,每行输入一个正整数n,请求出符合该方程要求的解数。
(1<=n<=1e9)
输出描述:
输出符合该方程要求的解数。
示例1
输入
复制
3
1
20180101
1000000000
输出
复制
1
5
181
数论,唯一分解定理
1/x+1/y=1/n,设x=n+a,y=n+b,化简可得n^2=a*b,
找出n^2的所有因子,根据数论中的唯一分解定理可得
任何整数n都可以表示为 n = p1^e1*p2^e2*..pn^en,
其中p1,p2…,pn都为素数,并且n的约数个数为(1+e1)*(1+e2)*…(1+en),
所以n^2 = (p1^e1*p2^e2…pn^en)^2 = (p1^2e1)*(p2^2e2)…*(pn^2en),所以因子个数为(1+2e1)*(1+2e2)*…(1+2en),所以可以利用唯一分解定理求出e1 e2…en,由于要满足x <= y所以只需找出a <= b的解的个数即可,设因子乘积为res,x<=y,所以res/2+1。
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
int num[2005];
int main(){
int T,n;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
int cnt=0;
memset(num,0,sizeof(num));
for(int i=2;i*i<=n;i++)
if(n%i==0){
while(n%i==0){
num[cnt]++;
n/=i;
}
cnt++;
}
if(n!=1){
num[cnt]++;
cnt++;
}
long long ans=1;
for(int i=0;i<cnt;i++)
ans*=(2*num[i]+1);
printf("%lld\n",ans/2+1);
}
return 0;
}
G.旋转矩阵
链接:https://ac.nowcoder.com/acm/contest/90/G
来源:牛客网
题目描述
景驰公司自成立伊始,公司便将“推动智能交通的发展,让人类的出行更安全,更高效,更经济,更舒适”作为公司使命,通过产业融合、建设智能汽车出行行业的方式,打造“利国、利民、利公司、利个人”的无人驾驶出行系统。公司的愿景是成为中国第一、世界一流的智能出行公司。
有一天,景驰公司的工程师在真车上做测试。
景驰公司的试验车上面有一个奇怪的图案,这是一个n*m的矩阵,这辆车可以到处开,每次可以左旋右旋,小明想知道转完之后的图案是怎么样的
具体来说:有一个n*m的字符矩阵,只包含3种字符(‘+’‘-’,‘|’),通过一通乱旋之后变成什么样子?
输入描述:
第一行测试样例数T(0<T<=100)
每个测试样例第一行两个正整数n,m(0<n,m<=30)
接下来的n行是一个n*m的字符矩阵
字符矩阵之后是一串只包含‘L’(左旋)和‘R’(右旋)的字符串,长度不超过1000
每个样例间输出一个空行
输出描述:
第一行两个正整数n,m
接下来的n行是一个n*m的字符矩阵
每个样例后面输出一个空行
示例1
输入
复制
2
2 3
+-+
|+|
LLRRR
3 2
-+
+|
-+
LLL
输出
复制
3 2
-+
+|
-+
2 3
|+|
+-+
备注:
左旋即逆时针旋转,右旋即顺时针旋转
-通过一次左旋或右旋会变成|
|通过一次左旋或右旋会变成-
简单的模拟题,记录旋转的次数,每4次R就回到原处,说明可以模4,L就--,R就++,除了0和180度外,其他都需要'|','-'的交换,最后别忘了每个样例之后输出一个空行= =
#include<iostream>
#include<cstdio>
using namespace std;
char ch[35][35];
int T,n,m,x;
int main(){
cin>>T;
while(T--){
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>ch[i][j];
x=0;
string s;
cin>>s;
for(int i=0;i<s.size();i++)
if(s[i]=='L')
x--;
else if(s[i]=='R')
x++;
x=(x%4+4)%4;
if(x==0){
cout<<n<<" "<<m<<endl;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++)
cout<<ch[i][j];
cout<<endl;
}
}else if(x==1){
cout<<m<<" "<<n<<endl;
for(int i=1;i<=m;i++){
for(int j=n;j>=1;j--)
if(ch[j][i]=='+')
cout<<ch[j][i];
else if(ch[j][i]=='-')
cout<<'|';
else
cout<<'-';
cout<<endl;
}
}else if(x==2){
cout<<n<<" "<<m<<endl;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++)
cout<<ch[n-i+1][m-j+1];
cout<<endl;
}
}else{
cout<<m<<" "<<n<<endl;
for(int i=m;i>=1;i--){
for(int j=1;j<=n;j++)
if(ch[j][i]=='+')
cout<<ch[j][i];
else if(ch[j][i]=='-')
cout<<'|';
else
cout<<'-';
cout<<endl;
}
}
cout<<endl;
}
return 0;
}
H.哲哲的疑惑
链接:https://ac.nowcoder.com/acm/contest/90/H
来源:牛客网
题目描述
哲哲有l个球,球是不同的,现在她要用n种颜色给它们染色,如果一种染色方案有k种颜色没有用到,那么哲哲会产生C(k,m)的不满意度。
现在哲哲想求所有方案的不满意度之和,然而她只知道1+1=9,而她的神犇朋友maple去FW战队当中单了不在她身边,所以并不会求,你能帮帮她吗?
输入描述:
三个数n,m,l
1<=n,m<=10^7,l<=10^18
输出描述:
一个数(对998244353取模),表示所有方案的不满意度之和
示例1
输入
复制
3 2 2
输出
复制
3
说明
有以下方案:
两个球同色,有2种颜色没有用到,哲哲产生C(2,2)=1的不满意度,然后这里有三种方案,共产生3的不满意度
两个球不同色,有1种颜色没有用到,哲哲很开心(*^▽^*)
所以总共产生3的不满意度
示例2
输入
复制
1634 1542 130
输出
复制
93812204
通过很低的组合数学
I.填空题
这题没有营养,直接输出ac就好
J.强迫症的序列
链接:https://ac.nowcoder.com/acm/contest/90/J
来源:牛客网
题目描述
牛客网是IT求职神器,提供海量C++、JAVA、前端等职业笔试题库,在线进行百度阿里腾讯网易等互联网名企笔试面试模拟考试练习,和牛人一起讨论经典试题,全面提升你的编程。作为acmer的小A,牛客网是他首选的题库。
小A是一个中度强迫症患者,每次做数组有关的题目都异常难受,他十分希望数组的每一个元素都一样大,这样子看起来才是最棒的,所以他决定通过一些操作把这个变成一个看起来不难受的数组,但他又想不要和之前的那个数组偏差那么大,所以他每次操作只给这个数组的其中n-1个元素加1,但是小A并不能很好的算出最优的解决方案,如果你能帮他解决这个问题,小A就能送你一个气球
输入描述:
第一行一个整数T(T<=100),表示组数
对于每组数据有一个n,表示序列的长度(0< n <100000)
下面一行有n个数,表示每个序列的值(0<ai<1000)
输出描述:
输出两个数
第一个数表示最小的操作步数
第二个数经过若干步以后的数组元素是什么
示例1
输入
复制
1
3
1 2 3
输出
复制
3 4
思维,贪心
每次操作n-1个数+1,可以等价于1个数-1,这样复杂度就从O(n)降到O(1)了,最小的数不会再减少了,再反过来思考,操作了多少次其实最小的数就会加多少,而这个数就是最后稳定的数
#include<iostream>
#include<cstdio>
using namespace std;
int main(){
int T,n;
int a[100005];
scanf("%d",&T);
while(T--){
int ans=0,m=9999;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
m = min(m,a[i]);
}
for(int i=1;i<=n;i++)
ans+=a[i]-m;
printf("%d %d\n",ans,m+ans);
}
return 0;
}
K.密码
链接:https://ac.nowcoder.com/acm/contest/90/K
来源:牛客网
题目描述
ZiZi登录各种账号的时候,总是会忘记密码,所以他把密码都记录在一个记事本上。其中第一个密码就是牛客网的密码。
牛客网专注于程序员的学习、成长及职位发展,连接C端程序员及B端招聘方,通过IT笔试面试题库、在线社区、在线课程等提高候选人的求职效率,通过在线笔试、面试及其他工具提升企业的招聘效率。
团队由来自Google、百度、阿里、网易等知名互联网巨头的热血技术青年组成,用户覆盖全国2000多所高校的100W求职程序员及全部一线互联网企业,并仍在高速增长中。
谨慎的ZiZi当然不会直接把密码记录在上面,而是把上面的字符串经过转化后才是真正的密码。转化的规则是把字符串以n行锯齿形写出来,然后再按从左到右,从上到下读取,
即为真正的密码。如ABABCADCE以3行写出:
所以真正的密码是ACEBBACAD。但是每一次都要写出来就太麻烦了,您如果能帮他写出一个转换程序,他就送你一个气球。
输入描述:
第一行一个整数T,表示数据组数
对于每组数据,首先一个正整数n(n<=100,000),然后下一行为一个字符串,字符串长度len<=100,000。
输出描述:
对于每组数据,输出一个字符串,代表真正的密码。
示例1
输入
复制
1
3
ABABCADCE
输出
复制
ACEBBACAD
找规律,分别写n=3,4,5,6的情况,你会发现除了第一行和最后一行是均匀2*n-2,其他的步数都是2*(n-i-1)与2*i交替
#include<stdio.h>
#include<string.h>
#include<string>
using namespace std;
char s[100005];
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("%d %s",&n,s);
if(n==1)
{
printf("%s\n",s);
continue;
}
int len=strlen(s);
string res;
for(int i=0;i<n;i++){
int k=i;
if(i==0||i==n-1){
while(k<len){
res+=s[k];
k+=2*n-2;
}
}
bool flag=true;
while(k<len){
res+=s[k];
k+=flag?2*(n-i-1):2*i;
flag=!flag;
}
}
printf("%s\n",res.c_str());
}
return 0;
}
L.用来作弊的药水
链接:https://ac.nowcoder.com/acm/contest/90/L
来源:牛客网
题目描述
在一个风雨交加的夜晚,来自异世界的不愿透露姓名的TMK同学获得了两种超强药水A、B。根据说明书,TMK知道了这两种药水的作用:
(1)药水A能使人的生命值提高,每饮用1个单位能使他生命值变成原来的x倍,即每饮用p个单位能使他的生命值变成原来的x^p(x的p次方)倍。
(2)药水B能使人的能量值提高,每饮用1个单位能使他能量值变成原来的y倍,即每饮用q个单位能使他的能量值变成原来的y^q(y的q次方)倍。
于是TMK迫不及待地喝下了所有的a个单位的药水A和b个单位的药水B,他立马体会到了自己能力的超强变化,然后他看了接下来的说明书:
药水A和药水B能互相抑制对方的负面效果,一旦生命值提升的倍数和能量值提升的倍数不相等,那么在五个小时后将会发生非常严重的后果。
于是TMK同学慌了,他想知道自己提升的生命值和能量值的倍数是否相等,由于他非常慌张,所以他把计算的重任交给你了。
作为埃森哲公司的一员,你觉得这个问题很简单,这得益于埃森哲公司分享知识的文化。
分享知识已成为埃森哲源远流长的文化。
埃森哲公司在帮助客户进行行之有效的知识管理的同时,它的管理层在其内部也进行了成功的知识管理的实践。如今,在埃森哲,分享知识已成为其源远流长的文化。在很大程度上,埃森哲公司的成功得益于其强大的知识管理系统。
输入描述:
第一行一个整数T,代表有T组数据。(1<=T<=5000)
每组数据仅一行,包含四个整数x,a,y,b,意义为题目描述。(1<=x,a,y,b<=10^9)
输出描述:
每组数据输出一行"Yes"或"No"(不包含双引号),表示TMK提升的生命值和能量值的倍数是否相等,相等为"Yes",不相等为"No"。
示例1
输入
复制
4
2 20 4 10
20 20 20 20
20 21 21 20
32768 32768 1048576 24576
输出
复制
Yes
Yes
No
Yes
这里不处理浮点误差也可以AC,不过最好处理下,10^(-9)一遍用这个,还有大佬用对数AC
还可以直接快速幂暴力 x^a%mod==y^b%mod,分别模上1e9+7,虽然题目没说模后结果,但这里对很大的素数求模不会影响答案
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main(){
int T;
double x,a,y,b;
scanf("%d",&T);
while(T--){
scanf("%lf%lf%lf%lf",&x,&a,&y,&b);
double v = a/b;
if(abs(pow(x,v)-y)<=0.0000001)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
typedef long double db;
const db eps=1e-9;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int x,a,y,b;
scanf("%d%d%d%d",&x,&a,&y,&b);
if(fabs(a*log(1.0L*x)-b*log(1.0L*y))<eps)printf("Yes\n");
else printf("No\n");
}
return 0;
}
/*
链接:https://www.nowcoder.com/acm/contest/90/L
来源:牛客网
4
2 20 4 10
20 20 20 20
20 21 21 20
32768 32768 1048576 24576
*/