A 跳台阶
Description
有一个n级台阶的楼梯,小明一开始在第0个台阶,小明一次可以向上跳1步,两步...甚至是n步,请问小明跳到n级台阶有多少种跳法?
Input
第一行输入一个整数t,代表有t组样例:( T<=30)
接下来的t行,都用一个整数n,表示楼梯有n级台阶( 1<=n<=30)
Output
输出跳到第n级台阶有多少种跳法
Sample Input
1
1
Sample Output
1
HINT
题解
因为每一步只能往前跳,而且可以任意跳,所以,可以由第 0 , 1 , ... , n - 1 级跳到第 n 级台阶很容易就可以推出第 n 级台阶的方案数,就是前 0 ~ n - 1 级台阶方案数的总和。第 0 级是 1,第 1 级也是 1,第 2 级是 2,第 3 级是 4 ... 因此第n(n > 0)级台阶就是 2 的(n - 1)次方。
标程
#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{
int num[33];
num[0]=1;
num[1]=1;
for(int i=2;i<33;i++)
num[i]=num[i-1]*2;
int n,t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
printf("%d\n",num[n]);
}
return 0;
}
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
输出
>
<
<
=
HINT
样例树如图:
对于询问5 7 0,编号5代表fa,编号7代表ea,字典序fa大于ea,故答案为>; 对于询问5 7 2,边权字母改变,编号5代表je,编号7代表kk,字典序je小于kk,故答案为<。
题解
树顶多 26 种状态,问题就是如何判断两节点字典序大小,若有两字符串的字符串 hash 数组,那么可以用二分寻找第一个不同字母的位置复杂度为 O(logn),那么可以先预处理出 26 棵树从根节点到叶子节点的字符串 hash 值,对于快速定位从某节点向上k步的位置可以用倍增法向上寻找,复杂度为 O(logn),那么每次询问的复杂度为 O((logn)^2)。总复杂度 O( 26n + nlogn +Q*(logn)^2 )。
标程
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <set>
#include <iostream>
#include <cstdlib>
#include <cmath>
using namespace std ;
typedef unsigned long long ull ;
const int maxn = 1e5 + 10 ;
int T , n ;
struct Pedge
{
int p , k ;
char aph ;
}P[maxn] ;
//建树
int head[maxn] , len ;
struct Edge
{
int to , next ;
Edge(){}
Edge(int t , int n) : to( t ) , next( n ) {}
}e[maxn];
void init()
{
memset( head , -1 , sizeof( head ) ) ;
len = 0 ;
}
void add_edge( int u , int v )
{
e[len] = Edge( v , head[u] ) ;
head[u] = len++ ;
}
//树的处理
int par[maxn][20] ;
void par_pre()
{
par[1][0] = 1 ;
for( int j = 1 ; j < 20 ; ++j )
for( int i = 1 ; i <= n ; ++i )
par[i][j] = par[par[i][j - 1]][j - 1] ;
}
//u节点向上走k步
int goback_k( int u , int k )
{
for( int j = 19 ; j >= 0 ; --j )
{
if( k & ( 1 << j ) )
{
k -= ( 1 << j ) ;
u = par[u][j] ;
}
}
return u ;
}
//hash
ull Hash[maxn][26] , pow_base[maxn] ;
const ull base = 131 ;
const ull mod = 1e9 + 7 ;
char change( char c , long long k , long long t )
{
k %= 26 ;
t *= k ;
t %= 26 ;
return ( c - 'a' + t ) % 26 + 'a' ;
}
void dfs_hash( int u , int t )
{
char aph = change( P[u].aph , P[u].k , t ) ;
Hash[u][t] = ( Hash[P[u].p][t] * base % mod + (aph - 'a') % mod ) % mod ;
for( int i = head[u] ; ~i ; i = e[i].next )
{
printf( "%d\n" , i ) ;
dfs_hash( e[i].to , t ) ;
}
}
void bfs_hash( int t )
{
queue<int> que ;
que.push( 1 ) ;
while( que.size() )
{
int u = que.front() ; que.pop() ;
for( int i = head[u] ; ~i ; i = e[i].next )
{
int to = e[i].to ;
char aph = change( P[to].aph , P[to].k , t ) ;
Hash[to][t] = ( Hash[u][t] * base % mod + (aph - 'a') % mod ) % mod ;
que.push( to ) ;
}
}
}
void init_hash()
{
for( int i = 0 ; i < 26 ; ++i )
{
//dfs_hash( 1 , i ) ;
bfs_hash( i ) ;
}
pow_base[0] = 1;
for(int i = 1; i <= 100001; i++ )
{
pow_base[i] = pow_base[i - 1] * base % mod ;
}
}
bool hash_cmp( int u , int v , int len , int t )
{
int fu = goback_k( u , len - 1 ) ;
int fv = goback_k( v , len - 1 ) ;
if( fu == 1 || fv == 1 ) return false ;
ull hash1 = ( Hash[u][t] - Hash[par[fu][0]][t] * pow_base[len] % mod + mod ) % mod ;
ull hash2 = ( Hash[v][t] - Hash[par[fv][0]][t] * pow_base[len] % mod + mod ) % mod ;
return hash1 == hash2 ;
}
//解决
char solve( int u , int v , int t )
{
if( change( P[u].aph , P[u].k , t ) > change( P[v].aph , P[v].k , t ) )
{
return '>' ;
}
if( change( P[u].aph , P[u].k , t ) < change( P[v].aph , P[v].k , t ) )
{
return '<' ;
}
int l , r ;
l = 1 ; r = n + 1 ;
while( r - l > 1 )
{
int mid = ( l + r ) >> 1 ;
if( hash_cmp( u , v , mid , t ) )
l = mid ;
else r = mid ;
}
int fu = goback_k( u , l ) ;
int fv = goback_k( v , l ) ;
if( change( P[fu].aph , P[fu].k , t ) > change( P[fv].aph , P[fv].k , t ) )
{
return '>' ;
}
if( change( P[fu].aph , P[fu].k , t ) < change( P[fv].aph , P[fv].k , t ) )
{
return '<' ;
}
return '=' ;
}
string s1 = "" , s2 = "" ;
int main()
{
scanf("%d",&T) ;
P[1].p = 0 , P[1].aph = 0 , P[1].k = 0 ;
P[0].p = 0 , P[0].aph = 0 , P[0].k = 0 ;
while( T-- )
{
scanf( "%d" , &n ) ;
init() ;
//输入
for( int i = 2 ; i <= n ; ++i )
{
scanf( "%d%*c%c%d" , &P[i].p , &P[i].aph , &P[i].k ) ;
add_edge( P[i].p , i ) ;
par[i][0] = P[i].p ;
}
par_pre() ;
init_hash() ;
int Q ;
scanf( "%d" , &Q ) ;
for( int i = 0 ; i < Q ; ++i )
{
s1 = "" ; s2 = "" ;
int u , v , t ;
scanf( "%d %d %d" , &u , &v , &t ) ;
printf( "%c\n" , solve( u , v , t % 26 ) ) ;
}
}
return 0 ;
}
C 平分游戏
转眼间又过了一年,又有一届的师兄师姐要毕业了。
有些师兄师姐就去了景驰科技实习。
在景驰,员工是他们最宝贵的财富。只有把每一个人的专业性和独特性结合在一起,他们才会获得成功。他们致力于为所有员工打造一个能够被激励,并分享公司成功的工作环境。
创新精神:为了改变人类出行而不断迎接全新挑战。
团队协作:依靠集体的智慧,坦诚无私地帮助彼此。
结果导向:在所有方面都力争做到中国第一和世界一流,并对结果负责。
共同成长:学习永无止境,通过个人发展和职业成长实现成就。
GUDTACM集训队教练孙壕又来请大家大搓一顿。
茶余饭足以后,有人提议不如来玩游戏吧。狼人杀谁是卧底跳一跳都已经玩得太多了,所以大家决定玩一个更加有挑战性的游戏。
集训队一共有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
题解:将环分成互不影响的gcd(n,k+1)个环,对于每个环最优的解是左右互给,所以只考虑想要达到avg的时候前后要互给多少就可以
以下转载大佬的解释
先看怎么处理没有kk的限制的问题,保证总数整除nn是必然的。
再来处理硬币的转移问题,对于相邻的两个位置A,BA,B来说,要么AA给BB,要么BB给AA,这样才能保证最优。
我们假设xixi为 第 ii 个人 给了 第 (i−1+n)%n(i−1+n)%n 个人 的硬币个数 (xi<0xi<0表示 后者给前者硬币)
假设平均值为avgavg,则有如下关系
对于第0个人 a0−x0+x1=avg→x1=x0−(a0−avg)→x1=x0−C0(C0=a0−avg)a0−x0+x1=avg→x1=x0−(a0−avg)→x1=x0−C0(C0=a0−avg)
对于第1个人 a1−x1+x2+avg→x2=x1−(a1−avg)→x2=x0−(a0+a1−2∗avg)→x2=x0−C1(C1=a0+a1−2∗avg)a1−x1+x2+avg→x2=x1−(a1−avg)→x2=x0−(a0+a1−2∗avg)→x2=x0−C1(C1=a0+a1−2∗avg)
最后的答案就是最小化 |x0|+|x1|+....|xn−2|=|x0|+|x0−C0|+|x0−C1|+....+|x0−Cn−2||x0|+|x1|+....|xn−2|=|x0|+|x0−C0|+|x0−C1|+....+|x0−Cn−2|
这个显然是在一个x轴上找到他们的中位数,答案最小。
现在来考虑存在kk的限制的问题,其实就将整个环分成了gcd(n,k+1)gcd(n,k+1)个独立的环,对每个环分别求解最后累加即可。
ps: 求中位数,之所以不用考虑奇偶,因为我们是拿中位数去减两边,最后中位数会被约掉
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>
#include <map>
#include <queue>
#include <stack>
#include <math.h>
#include <string>
using namespace std;
typedef long long ll;
const int N = 1e6+7;
int a[N],vis[N];
ll b[N];
ll middle(int cnt)
{
b[cnt-1]=0;
sort(b,b+cnt);
return b[cnt/2];
}
int main()
{
int n,k;
scanf("%d%d",&n,&k);
ll sum=0;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
sum+=a[i];
}
k=min(k,n-1);
if(sum%n!=0){
puts("gg");
return 0;
}
ll minn=0,avg = sum/n;
for(int i=0;i<n;i++)
{
if(!vis[i])
{
int cnt=0,j=i;
ll p=0,pp=0;
while(!vis[j])
{
b[cnt]=a[j]-avg+p,pp+=a[j];
p=b[cnt++];
vis[j]=1;
j=(j+k+1+n)%n;
}
if(pp%cnt!=0||pp/cnt!=avg)
{
puts("gg");
return 0;
}
ll ans=middle(cnt);
for(int k=0;k<cnt;k++)
{
minn+=abs(ans-b[k]);
}
}
}
printf("%lld\n",minn);
return 0;
}
D psd面试
掌握未来命运的女神 psd 师兄在拿了朝田诗乃的 buff 后决定去实习。
埃森哲公司注册成立于爱尔兰,是一家全球领先的专业服务公司,为客户提供战略、咨询、数字、技术和运营服务及解决方案。他们立足商业与技术的前沿,业务涵盖40多个行业,以及企业日常运营部门的各个职能。凭借独特的业内经验与专业技能,以及翘楚全球的交付网络,他们帮助客户提升绩效,并为利益相关方持续创造价值。埃森哲是《财富》全球500强企业之一,目前拥有约41.1万名员工,服务于120多个国家的客户。于是psd打算去埃森哲公司投一下简历。
于是他用英文写了一篇简历,由于手速太快了以致自己都不知道写了什么。
然而面试官 xwc 一眼就看到了重点:大学打过 ACM!
xwc:“
听说你很低袄?考你个题:
忽略字母大小写,你这篇简历去掉最长的回文子序列后还有多长?
”
psd 顺手就把这个问题抛给了你。
输入描述:
多组输入,每组输入一个长度不超过 1234 的没空格的字符串,是 psd 的简历。
输出描述:
每组输出一个整数,如题。
示例1
输入
google
输出
2
示例2
输入
aBc,bAd
输出
2
题解
等价于求最长公共子序列,把字符串倒过来进行匹配
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>
#include <map>
#include <queue>
#include <stack>
#include <math.h>
#include <string>
using namespace std;
typedef long long ll;
const int N = 1e5+9;
char ss[1500],st[1500];
int dp[1500][1500];
int main()
{
while(~scanf("%s",ss))
{
int len=strlen(ss);
for(int i=0;i<len;i++)
{
if(ss[i]>='A'&&ss[i]<='Z')
{
int k=ss[i]-'A';
ss[i]='a'+k;
}
}
for(int i=0,j=len-1;j>=0;i++,j--)
{
st[i]=ss[j];
}
memset(dp,0,sizeof(dp));
for(int i=0;i<len;i++)
{
for(int j=0;j<len;j++)
{
if(ss[i]==st[j])dp[i+1][j+1]=dp[i][j]+1;
else dp[i+1][j+1]=max(dp[i+1][j],dp[i][j+1]);
}
}
printf("%d\n",len-dp[len][len]);
}
return 0;
}
E 回旋星空
Description
曾经有两个来自吉尔尼斯的人(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的一声哭了出来
Input
第一行一个整数T(T<=10),表示组数
对于每组数据有一个n,表示有n个小星星(0< n < 1000)
接下来跟着n行,每行跟两个整数xi和yi表示每个星星的坐标(-10000< xi, yi<10000)
Output
对于每组数据,如果没有找到回旋图标输出”WA”,否则输出找到图标个数
Sample Input
2
2
1 0
0 1
3
1 0
0 1
0 0
Sample Output
WA
2
HINT
没有重复的星星,且选中的三个星星是互相不一样的(即下标不同)
欧氏距离即直线距离
题解
题意就是给你若干个点,问你存在几组点,满足题目的条件 d(a[i],a[j]) == d(a[j],a[k])
那你可以枚举转折点,然后在用这个转折点去扫其他的点,求这个转折点与其他点的距离,存起来,判断每个距离的出现次数是否大于等于 2,如果大于就算一下排列数(正反算不同的)加到 ans 上。
标程
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100005;
int x[maxn];
int y[maxn];
map<int,int>maple;
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d %d",&x[i],&y[i]);
int ans = 0;
for(int i=0;i<n;i++)
{
maple.clear();
for(int j=0;j<n;j++)
{
if(i==j)
continue;
int dx = (x[i]-x[j])*(x[i]-x[j]);
int dy = (y[i]-y[j])*(y[i]-y[j]);
maple[dx+dy]++;
}
for(auto &cnt: maple)
{
int tmp = cnt.second;
if(tmp>=2)
ans += (tmp-1)*tmp/2;
}
}
if(ans==0)
cout<<"WA"<<endl;
else
cout<<ans<<endl;
}
return 0;
}
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
-->
nx+ny=xy
-->
(n-x)*(n-y)=n*n
转化为求 n*n 小等于 n 的因子的个数,由于 n达到 10^9,直接求太大。
将 n 分解质因子,复杂度为 logn,n*n 对应的质因子和 n 相同,且个数翻倍,即可得到 n*n 的质因子个数。
即 n*n=s1^x1*s2^x2*.......... s1,s2......为质因子,因此对于s1有x1+1(0,1,....x1)种选择,所以质因子的总数为
(x1+1)*(x2+1)*.......(xn+1) 由于求n*n的质因子太大了,所以就转成求n的质因子xx1,然后x1=2*xx1;
所以总数为(2*xx1+1)*(2*xx2+1)*....... 由于x<=y 所以就为一半解
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>
#include <map>
#include <queue>
#include <stack>
#include <math.h>
#include <string>
using namespace std;
typedef long long ll;
const int N = 1e5+100;
int prime[N],mark[N],cnt;
void pre()
{
cnt=0;
for(int i=2;i<=N;i++)
{
if(mark[i]==0)
{
prime[cnt++]=i;
for(int j=i;i+j<=N;j+=i)
{
mark[j]=1;
}
}
}
}
int solve(int n)
{
int ans=1,t;
for(int i=0;prime[i]*prime[i]<=n&&i<cnt;i++)
{
t=0;
while(!(n%prime[i]))
{
t++;
n/=prime[i];
}
ans*=2*t+1;
}
if(ans==1||n!=1)ans*=3;
return ans;
}
int main()
{
pre();
int t;scanf("%d",&t);
while(t--)
{
int n;scanf("%d",&n);
int ans=solve(n);
if(n==1)printf("1\n");
else printf("%d\n",(ans+1)/2);
}
return 0;
}
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
|+|
+-+
备注:
左旋即逆时针旋转,右旋即顺时针旋转
-通过一次左旋或右旋会变成|
|通过一次左旋或右旋会变成-
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>
#include <map>
#include <queue>
#include <stack>
#include <math.h>
#include <string>
using namespace std;
typedef long long ll;
char s[37][37];
char s2[37][37];
string s1;
int main()
{
int t;scanf("%d",&t);
while(t--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
scanf("%s",s[i]);
}
cin>>s1;
int l=0,r=0;
for(int i=0;i<s1.size();i++)
{
if(s1[i]=='L')l++;
else r++;
}
int cnt = abs(l-r)%4;
if(l<=r)
{
if(cnt==0){
printf("%d %d\n",n,m);
for(int i=0;i<n;i++)
printf("%s\n",s[i]);
}
else if(cnt==1)
{
printf("%d %d\n",m,n);
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
s2[i][j]=s[n-1-j][i];
}
}
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(s2[i][j]=='-')s2[i][j]='|';
else if(s2[i][j]=='|')s2[i][j]='-';
}
}
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
printf("%c",s2[i][j]);
}
printf("\n");
}
}
else if(cnt == 2 )
{
printf("%d %d\n",n,m);
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
s2[i][j]=s[n-1-i][m-1-j];
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
printf("%c",s2[i][j]);
}
printf("\n");
}
}
else if(cnt == 3)
{
printf("%d %d\n",m,n);
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
s2[i][j]=s[j][m-1-i];
}
}
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(s2[i][j]=='-')s2[i][j]='|';
else if(s2[i][j]=='|')s2[i][j]='-';
}
}
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
printf("%c",s2[i][j]);
}
printf("\n");
}
}
}
else {
if(cnt==0){
printf("%d %d\n",n,m);
for(int i=0;i<n;i++)
printf("%s\n",s[i]);
}
else if(cnt==3)
{
printf("%d %d\n",m,n);
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
s2[i][j]=s[n-1-j][i];
}
}
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(s2[i][j]=='-')s2[i][j]='|';
else if(s2[i][j]=='|')s2[i][j]='-';
}
}
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
printf("%c",s2[i][j]);
}
printf("\n");
}
}
else if(cnt == 2 )
{
printf("%d %d\n",n,m);
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
s2[i][j]=s[n-1-i][m-1-j];
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
printf("%c",s2[i][j]);
}
printf("\n");
}
}
else if(cnt == 1)
{
printf("%d %d\n",m,n);
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
s2[i][j]=s[j][m-1-i];
}
}
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(s2[i][j]=='-')s2[i][j]='|';
else if(s2[i][j]=='|')s2[i][j]='-';
}
}
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
printf("%c",s2[i][j]);
}
printf("\n");
}
}
}
printf("\n");
}
return 0;
}
H 哲哲的疑惑
Description
哲哲有l个球,球是不同的,现在她要用n种颜色给它们染色,如果一种染色方案有k种颜色没有用到,那么哲哲会产生C(k,m)的不满意度。
现在哲哲想求所有方案的不满意度之和,然而她只知道1+1=9,而她的神犇朋友maple去FW战队当中单了不在她身边,所以并不会求,你能帮帮她吗?
Input
三个数n,m,l
1<=n,m<=10^7, l<=10^18
Output
一个数(对998244353取模),表示所有方案的不满意度之和
Sample Input
3 2 2
1634 1542 130
Sample Output
3
93812204
HINT
样例1
有以下方案:
两个球同色,有2种颜色没有用到,哲哲产生C(2,2)=1的不满意度,然后这里有三种方案,共产生3的不满意度
两个球不同色,有1种颜色没有用到,哲哲很开心(▽)
所以总共产生3的不满意度
样例2
无可奉告
题解
答案显然是下式(相当于枚举一个 i 表示我用了 i 种颜色)
标程
#include <cstdio>
using namespace std;
#define Mod 998244353
#define N 30000050
int n,m,i,ni[N];
long long l;
inline int qmi(int di,long long zhi)
{
int ret=1,x=di;
while (zhi){
if (zhi&1) ret=1LL*ret*x%Mod;
x=1LL*x*x%Mod;zhi>>=1;
}return ret;
}
int main()
{
scanf("%d%d%lld",&n,&m,&l);
int ans=1;
for (i=n-m+1;i<=n;i++) ans=1LL*ans*i%Mod;
ni[1]=1;
for (i=2;i<=m;i++) ni[i]=-1LL*(Mod/i)*ni[Mod%i]%Mod;
for (i=1;i<=m;i++) ans=1LL*ans*ni[i]%Mod;
ans=1LL*ans*qmi(n-m,l)%Mod;
printf("%d\n",(ans+Mod)%Mod);
return 0;
}
I 填空题
题意: 直接输出ac即可
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>
#include <map>
#include <queue>
#include <stack>
#include <math.h>
using namespace std;
typedef long long ll;
int main()
{
printf("ac\n");
return 0;
}
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
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>
#include <map>
#include <queue>
#include <stack>
#include <math.h>
#include <string>
using namespace std;
typedef long long ll;
const int N = 1e5+9;
int a[N];
int main()
{
int t;scanf("%d",&t);
while(t--)
{
int n;scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
sort(a,a+n);
int sum=0;
for(int i=0;i<n-1;i++)
{
sum+=a[i]-a[0];
}
int cnt=a[n-1]+sum;
int ans=cnt-a[0];
printf("%d %d\n",ans,cnt);
}
return 0;
}
K 密码
链接:https://www.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。
输出描述:
对于每组数据,输出一个字符串,代表真正的密码。
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>
#include <map>
#include <queue>
#include <stack>
#include <math.h>
using namespace std;
typedef long long ll;
char s[100009];
int main()
{
int t;scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
scanf("%s",s+1);
int cnt=0;
int len = strlen(s+1);
if(n==1)printf("%s",s+1);
else {
for(int i=1;i<=n;i++)
{
if(i>1)cnt+=2;
for(int j=i;j<=len;j+=2*(n-1))
{
printf("%c",s[j]);
if(i>1&&j+2*(n-1)-cnt<=len&&i!=n)
{
printf("%c",s[j+2*(n-1)-cnt]);
}
}
}
}
printf("\n");
}
return 0;
}
L yon
在一个风雨交加的夜晚,来自异世界的不愿透露姓名的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
指数做法
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>
#include <map>
#include <queue>
#include <stack>
#include <math.h>
using namespace std;
typedef long long ll;
int main()
{
int n;
scanf("%d",&n);
while(n--)
{
double x,a,y,b;
scanf("%lf%lf%lf%lf",&x,&a,&y,&b);
if((ll)(a*(double)log10(x))==(ll)(b*(double)log10(y)))printf("Yes\n");
else printf("No\n");
}
return 0;
}