18广工校赛题目

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;
}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值