黑龙江大学程序设计竞赛(重现赛) 个人笔记 题解

题目链接:https://ac.nowcoder.com/acm/contest/877#question

 

A.Find the Nth Character

链接:https://ac.nowcoder.com/acm/contest/877/A
来源:牛客网
 

题目描述

今天在给

的同学们上程序算法课的时候出了一道找规律的题目,题目表述如下

假设:

现在要求上课的同学们把所有的串依次连接起来,于是得到:

那么你能告诉串中的第个字母是多少吗?
 


 

 

输入描述:

输入首先是一个数字,代表有次询问

接下来的行每行有一个整数

 

输出描述:

对于每次询问,输出串中第个位置对应的字母。

示例1

输入

复制

6
1
2
3
4
5
10

输出

复制

a
a
b
a
b
d

 

#include<iostream>
#include<cstdio>
using namespace std;

char ch[10555];

int main(){
    int tot=0;

    while(tot<=10000)
    for(int i=1;i<=1000;i++){
        for(int j=0;j<i;j++){
            ch[++tot] = (char)('a'+j%26);
            if(tot>10000) break;
        }
            if(tot>10000) break;
    }


    int T,n;
    scanf("%d",&T);

    while(T--){
        scanf("%d",&n);
        printf("%c\n",ch[n]);
    }

	return 0;
}

 

B.Help Me

链接:https://ac.nowcoder.com/acm/contest/877/B
来源:牛客网
 

题目描述

有一天Miss Quan出了一个题,给出一个长度为的数组

Miss Quan说给我计算下这个权值等于多少,然后随手写了一个式子,把她的小伙伴们都给惊呆了,这是什么鬼......

比如

听到这里,小伙伴们说这不是很简单吗,于是写出了下面的代码:

Miss Quan会心一笑,大家意识到事情并不简单,这个解法时间复杂度太高了,你能想出更好的计算Value的方法吗?只需要输出Value的值即可。

输入描述:

 

第一行输入一个整数代表共有组数据

对于每组测试用例第一行输入一个整数第二行输入个数

 

输出描述:

 

对于每组数据,输出一行,一个整数代表的值.

 

 

示例1

输入

复制

2
3
1 4 2
2
10 20

输出

复制

14
100

示例2

输入

复制

1
4
5 6 8 7

输出

复制

20

 

 思路 : 比如4个数a_{1}a_{2}a_{3}a_{4},答案应该是它们(a_{1}-a_{2})^{2},(a_{1}-a_{4})^{2},(a_{2}-a_{4})^{2},(a_{3}-a_{4})^{2},(a_{1}-a_{3})^{2},(a_{2}-a_{3})^{2}的和,我们拆开发现,(n-1)*(a_{1}^{2}+a_{2}^{2}+a_{3}^{2}+a_{4}^{2})-2a_{1}a_{2}-(a_{1}+a_{2})*a_{3}-(a_{1}+a_{2}+a_{3})*a_{4},这样我们维护个前缀和就好了。

前缀和 找规律+思维,空间不爆就longlong

#include<iostream>
#include<cstdio>
using namespace std;

const int MAX  = 5*1e5+5;
typedef long long ll;
ll sum[MAX],a[MAX];
int T,n;

int main(){
    scanf("%d",&T);
    while(T--){
        sum[0]=0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%lld",&a[i]);
            sum[i] = sum[i-1] + a[i];
        }
        ll ans = (n-1)*a[1]*a[1];
        for(int i=2;i<=n;i++){
            ans+=(n-1)*a[i]*a[i];
            ans+=(-2)*sum[i-1]*a[i];
        }

        printf("%lld\n",ans);
    }

	return 0;
}

 

C.Challenge IQ

链接:https://ac.nowcoder.com/acm/contest/877/C
来源:牛客网
 

题目描述

爱的魔力转圈圈,想你想到心花怒放黑夜白天,可是我害怕爱情只是一瞬间,转眼会不见,我要慢慢冒险。经过了无数的思想斗争,他要做出这个决定,和喜欢的女孩子表白,但女孩只是留给他一个排列,排列的定义是一个由组成的序列每个数出现并且只出现1次。

 

现在他需要把个数通过一定顺序首尾连接形成一个圆环,使得相邻元素互质的对数尽可能多,请输出最大的对数。两个数互质的定义是这两个数的GCD(最大公约数)为1。比如6和4的最大公约数为2,不互质。4和3的最大公约数为1,互质。

 

输入描述:

 

第一行是一个数字,表示共有T组测试数据.

接下来行,每行一个数字.

 

输出描述:

一行一个整数表示答案

示例1

输入

复制

2
3
5

输出

复制

3
5

不知道想考什么,就普通的排序1,2,3,...,n都已经是n了 

#include<iostream>
#include<cstdio>
using namespace std;

int main(){
    int T,n;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        printf("%d\n",n);
    }

	return 0;
}

 

D.Schedules

链接:https://ac.nowcoder.com/acm/contest/877/D
来源:牛客网
 

题目描述

 

输入

复制

3
1 3
4 6
2 5

输出

复制

2

示例2

输入

复制

2
0 4
4 5

输出

复制

1

示例3

输入

复制

4
2 4
1 3
5 9
3 8

输出

复制

2

 

E.Pig-Palindromic

 链接:https://ac.nowcoder.com/acm/contest/877/E
来源:牛客网
 

题目描述

 

输入

复制

AabBAD

输出

复制

4

示例2

输入

复制

ACda

输出

复制

0

示例3

输入

复制

CCcc

输出

复制

4

示例4

输入

复制

A

输出

复制

0

类最长回文子串,中心扩展 

#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
using namespace std;

int main(){
    string s;
    cin>>s;
    int n=s.size();
    int ans=0;

    for(int i=0;i<n;i++){
        int res=0;
        for(int j=i,k=i+1;j>=0&&k<n;j--,k++)//中心扩展,类回文串处理
            if(abs(s[j]-s[k])==32)
                res+=2;
            else
                break;

        ans = max(ans,res);
    }

    cout<<ans<<endl;
	return 0;
}

 

 

F.GCD Problem

链接:https://ac.nowcoder.com/acm/contest/877/F
来源:牛客网
 

题目描述

输入描述:

 

输入

复制

4
5 45 20 65
7
1 1 4
0 1 4
1 1 4
1 3 4
0 3 4
1 3 4
1 2 2

输出

复制

5
2
4
2
6

 

G.Bash Game

链接:https://ac.nowcoder.com/acm/contest/877/G
来源:牛客网
 

题目描述

The two new cute boys(Alice and Bob) in the ACM group of HLJU science and technology association have been dreaming of getting these six books written by Mr Jin.

 

As we all know, there is no such thing as a free lunch. Mr Jin now lets Alice and Bob play a game,and only the winner of the game can get these six books.The rules of the game are as follows.

 Suppose(假设) the price of these six books is P, two people take turns in bidding(竞拍), Suppose one party(一方) bid A yuan during the bidding process and the other party(另一方) bid B yuan. Rules require . In this way, the bidding goes on in turn until the price of one party is greater than or equal toP,the party fails and the game ends, Mr Jin awarded these books to another party.

 

Alice first bid, Bob bid behind him every time, and Alice and Bob use the best strategy(最优策略), who can get these books?

 

输入

复制

4
1 1
20 6
10 2
23 7

输出

复制

Bob
Alice
Bob
Alice

巴什博奕,模板是 p%(m+1)==0,大概靠一下就能出答案了

#include<iostream>
#include<cstdio>
using namespace std;

int main(){
    int T,p,m;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&p,&m);
        if(p%(m+1)==1)
            printf("Bob\n");
        else
            printf("Alice\n");
    }

	return 0;
}

 

H.Pass CET 6

链接:https://ac.nowcoder.com/acm/contest/877/H
来源:牛客网
 

题目描述

Marzz liked a strange way of memorizing words.

 Now these words are placed in an  Matrix. He decided to memorize only one line or one column of words every day. She has memorized days in total, and now she wants to know: for each word, when was the last time she memorized it?

 

输入

复制

3 3 3
1 2
2 3
1 3

输出

复制

0 0 2
1 1 2
3 3 3

 

#include<iostream>
#include<cstdio>
using namespace std;

const int MAX =1e5+5;
int vis[3][MAX];
int n,m,T,x,y;

int main(){

    scanf("%d%d%d",&n,&m,&T);

    for(int i=1;i<=T;i++){
        scanf("%d%d",&x,&y);
        vis[x][y] = i;
    }

    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            if(j!=m)
                printf("%d ",max(vis[1][i],vis[2][j]));
            else
                printf("%d\n",max(vis[1][i],vis[2][j]));
    }



	return 0;
}

 

I.Center Street

链接:https://ac.nowcoder.com/acm/contest/877/I
来源:牛客网
 

题目描述

在哈乐冰的中央大街上有N个仓买, 我们可以将其抽象为一条线段上有N个顶点,仓买在线段上是均匀分布的,也就是说1号仓买在顶点1这个位置,2号仓买在顶点2这个位置...N号仓买在N这个位置。刚开始这些仓买之间是互相不通的,为了交流,工程师们建了一些路,但是由于资金有限,并不能在两两之间建一条路,他们只能有选择的建一些路。如果两个仓买A,B满足A是B的倍数,则A,B之间可以通一条路,当然这些路是双向的,A可以到B,B可以到A

例如N=8的时候:

仓买1向所有其他仓买通一条路。

2号仓买向4,6,8号仓买通路。

3号仓买仅和6号仓买通路。

4号仓买仅和8号仓买通路。

众所周知,建路需要花费很大一笔钱,所以资本家们需要过路的人需要收取一定费用,如果仓买A,B之间通路,则过路费为元。

现在小M站在1号仓买上,他想得知他分别到达1,2,3...N号仓买的最小花费。虽然他可以直接从1号仓买到达其他仓买,但是可以通过中转的方式让花费更少。你能帮帮他吗?

输入描述:

输入一个整数,表示共有N个仓买。

输出描述:

一行,输出N个整数,以空格隔开,分别代表从1号仓买到其他仓买的最小花费。

示例1

输入

复制

8

输出

复制

0 1 4 5 16 13 36 21

说明

1号到1号仓买自身,不需花费,为0

1号到2号仓买,直接到达,花费

1号到3号仓买,直接到达,花费

1号到4号仓买,直接到达花费9。但是可以先到达2,再通过2到4的路到达,花费为

1号到5号仓买,直接到达,花费16

1号到6号仓买,1->3->6,花费13

1号到7号仓买,1->7,花费36

1号到8号仓买,通过1->2->4->8,花费为21

倍筛思想,细节,注意longlong,还有i*i之类的写成(ll)i*i,写成(ll)(i*i)也是不行的

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

typedef long long ll;
const int MAX = 5*1e5+5;
ll a[MAX];
int n;

int main(){
    scanf("%d",&n);
    memset(a,999999,sizeof(a));
    a[1]=0;
    for(int i=1;i<=n;i++)
        for(int j=2*i;j<=n;j+=i)
            a[j] = min(a[j],a[i]+(ll)(j-i)*(j-i));
    for(int i=1;i<=n;i++)
        printf("%lld ",a[i]);
    printf("\n");
	return 0;
}

 

 J.Special Distance

链接:https://ac.nowcoder.com/acm/contest/877/J
来源:牛客网
 

题目描述

 

输入

复制

2
2
4 3
4
5 4 -9 2

输出

复制

10
84

 题意:求最大FST距离,即\left | \left ( i^{2}-j^{2} \right ) \right |+\left | A^{2}_{i}-A^{2}_{j} \right |.
思路:我们可以令i>j,则上式有两种情况:
=i^2-j^2+Ai^2-Aj^2=i^2+Ai^2-(j^2+Aj^2);
或=i^2-j^2-Ai^2+Aj^2=i^2-Ai^2-(j^2+Aj^2);
故我们只需要分别求出i^2+Ai^2与i^2-Ai^2的最大最小值,然后求出最大最小值差的最大值。

#include<iostream>
#include<cstdio>
using namespace std;

const int MAX = 3*1e5+5;
typedef long long ll;

ll a[MAX],max1=-99999999,max2=-99999999,min1=99999999,min2=999999999;

int main(){
    int T,n;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        max1=-99999999,max2=-99999999,min1=99999999,min2=999999999;
        for(int i=1;i<=n;i++){
            scanf("%lld",&a[i]);
            max1 = max(max1,(ll)i*i+a[i]*a[i]);
            max2 = max(max2,(ll)i*i-a[i]*a[i]);
            min1 = min(min1,(ll)i*i+a[i]*a[i]);
            min2 = min(min2,(ll)i*i-a[i]*a[i]);
        }
        ll ans = max(max1-min1,max2-min2);
        printf("%lld\n",ans);
    }

	return 0;
}

 

K.Maximum Sum of Digits

链接:https://ac.nowcoder.com/acm/contest/877/K
来源:牛客网
 

题目描述

 

输入

复制

2
35
1000000000

输出

复制

17
82

说明

In the first example, you can choose, for example,a = 17 andb = 18, so thatS(17) + S(18) = 1 + 7 + 1 + 8 = 17. It can be shown that it is impossible to get a larger answer.

In the second test example, you can choose, for example,a = 500000001 andb = 499999999, withS(500000001) + S(499999999) = 82. It can be shown that it is impossible to get a larger answer.

思维,让位数中的9尽量多 

#include<iostream>
#include<cstdio>
using namespace std;

typedef long long ll;

ll findNine(ll x){
//    if(x<=9)
//        return x;
    ll ans = 0;
    while(x/10>0){
        ans = 10*ans+9;
        x/=10;
    }

    return ans;
}

ll S(ll x){
    ll ans=0;
    while(x>0){
        ans+=x%10;
        x/=10;
    }

    return ans;
}

int main(){
    int T;
    ll n;
    scanf("%d",&T);
    while(T--){
        scanf("%lld",&n);
        ll x = findNine(n);
        printf("%lld\n",S(x)+S(n-x));
        //printf("%lld %lld %lld\n",x,n-x,S(x)+S(n-x));
    }


	return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值