2019河北省大学生程序设计竞赛(重现赛)

B:

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

题目描述

Icebound hates math. But Imp loves math. One day, Imp gave icebound a problem.

The problem is as follows.

S=(∑ni=1qi) mod pS=(∑i=1nqi) mod p

For given q,n,p, you need to help icebound to calculate the value of S.

输入描述:

The first line contains an integer T, denoting the number of test cases.
The next T lines, each line contains three integers q,n,p, separated by spaces. 
1≤T≤1001≤T≤100, 1≤n,q,p≤1091≤n,q,p≤109

输出描述:

For each test case, you need to output a single line with the integer S.

示例1

输入

复制

2
2 3 100
511 4 520

输出

复制

14
184

题解: 简单的等比数列求和

#include<bits/stdc++.h>
using namespace std;
typedef long long  ll;
#define clr(a,b) memset(a,b,sizeof(a))
ll q,n,p;
ll tpow(ll a,ll b,ll mod)
{
    ll ans=1;
    while(b)
    {
        if(b&1){ans*=a;}
        a*=a;
        a%=mod;
        ans%=mod;
        b>>=1;
    }
    return ans;
}
long long T(long long n)//等比数列快速求和核心公式
{
    if(n == 1) return q;
    if(n % 2 == 0)
    {
        return (tpow(q,n/2,p)+1)%p * T(n/2)%p;
    }
    else
    {
        return (tpow(q,n,p) + T(n-1))%p;
    }
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        cin>>q>>n>>p;
        cout<<T(n)<<endl;
    }
    return 0;
}

C

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

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 65536K,其他语言131072K
64bit IO Format: %lld

题目描述

你是DEEP国的大军师,辅佐一个非常有野心的国王,这位国王非常有野心,他计划攻占 n 个国家。在地图上,这些国家排成一行。

探子已经查明,当攻打一个国家 i 时,为了防止国家间的联合对抗,需要给该国家周围,所有未被攻占的国家支付costicosti 个金币,即对于国家 i,它左侧第一个已被攻打的国家为 l,右侧第一个已被攻打的国家为 r,则他需要给[l+1,i-1] 和 [i+1,r-1] 之间的国家支付金币。如果 l 不存在,则需要给 [1, i-1] 之间的所有国家支付金币;若 r 不存在,则需要给 [i+1,n] 之间的所有国家支付金币。

现在,你的下属已经给你提供了每个国家需要支付金币的数量。为了满足国王的野心,你需要计算出攻占完所有国家需要的最小花费。

输入描述:

第一行是一个整数 T,代表接下来有T组数据。
接下来每组数据
第一行有一个整数 n,代表要攻占的国家数目。
第二行共 n 个整数,代表攻占每个国家前,需要支付给其周围未被攻占国家 costicosti个金币。
1≤T≤501≤T≤50,1≤n≤1001≤n≤100,1≤costi≤100001≤costi≤10000

输出描述:

对于每组数据输出一行,代表需要支付的最小花费。

示例1

输入

复制

2
1
1
3
1 1 2

输出

复制

0
2

说明

3
1 1 2
先打中间这个1 给左右两个各1块钱
再打左右两个 不用花钱

题解:区间DP维护dp[i][j] 表示攻打这段城市所需要的最少费用

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
#define clr(a,b) memset(a,b,sizeof(a))
typedef long long ll;
const int inf = 0x3f3f3f3f3f3f3f3f;
int n;
int num[102], dp[102][102];

int main()
{
	int t;
	cin >> t;
	clr(dp, 1);
	while (t--)
	{
		cin >> n;
		int sum = 0;
		for (int i = 1; i <= n; ++i)
		{
			cin >> num[i];
		}
		for (int i = 1; i <= n; ++i) { dp[i][i] = 0; }
		//dp[i][j]表示攻打i到j这一段城市需要花费的最少费用
		for (int len = 1; len <= n; ++len)
		{
			for (int i = 1; i + len <= n; ++i)
			{
				int j = i + len;
				dp[i][j] = inf;
				for (int k = i + 1; k < j; ++k)//在区间i-j第一个攻占的城市
				{
					dp[i][j] = min(dp[i][j], dp[i][k - 1] + dp[k + 1][j] + len* num[k]);
				}
				dp[i][j] = min(dp[i][j], dp[i + 1][j] + num[i] * len);
				dp[i][j] = min(dp[i][j], dp[i][j - 1] + num[j] * len);
			}
		}
		cout << dp[1][n] << endl;
	}
	return 0;
}

E

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

题目描述

There are n boys, indexed from 1 to n, and n girls indexed from n+1 to 2n.
One day, they have a party together. The girls are seated in the first row, and the boys sit in the second row. They take their seat in such a way, that a boy sit just behind a girl, and boy indexed 1 sit on the leftmost chair, 2 sit on the second, etc.
Each boy has a girl he likes,and he may make contact to his sweetheart, by writing down what he wants to tell her on a piece of paper, and makes it a paper plane, which he will throw directly at her. You may assume that the plane will go in a straight line.
But, the trouble occurs, when two paper plane collide in the air and drop halfway. Obviously, this will be extremely awkward. So each boy wants to know, if he throws his paper plane, how many paper planes have the potential to collide with it halfway.
It's guaranteed that each girl is the sweetheart of exactly one boy.

输入描述:

The first line contains a single integer n.
Then n lines follow, the i-th of which contains two integers, the index of the girl seated in front of the i-th boy and the girl he likes.
1≤n≤1051≤n≤105

输出描述:

Output n lines, the i-th of which contains one integer, the number of planes that may collide with i-th boy's plane.

示例1

输入

复制

5
7 9
6 6
8 10
9 7
10 8

输出

复制

3
2
2
3
2

 题解:计算会与左边的形成的交集,与右边会形成的交集,用数状数组维护。

#include<bits/stdc++.h>
using namespace std;
#define clr(a,b) memset(a,b,sizeof(a))
#define lowbit(x)  x&(-x)
typedef long long ll;
const int maxn=1000000+2;
int n,boy[maxn],girl[maxn],tree[maxn],l[maxn],count1[maxn],count2[maxn];
int sum(int x){
    int ans=0;
    while(x)
    {
        ans+=tree[x];
        x-=lowbit(x);
    }
    return ans;
}
void add(int x,int w){
    while(x<=n)
    {
        tree[x]+=w;
        x+=lowbit(x);
    }
}
int main()
{
    cin>>n;
    int fr,li;
    for(int i=1;i<=n;++i)
    {
        cin>>fr>>li;
        boy[i]=li;girl[fr]=i;
    }
    for(int i=1;i<=n;++i){l[i]=girl[boy[i]];}
    clr(tree,0);
    for(int i=1;i<=n;++i)//计算左边
    {
        count1[i]=sum(n)-sum(l[i]);
        add(l[i],1);
    }
    clr(tree,0);
    for(int i=n;i>=1;--i){//计算右边
        count2[i]=sum(l[i]-1);
        add(l[i],1);
    }
    for(int i=1;i<=n;++i) cout<<(count1[i]+count2[i])<<endl;
    return  0;
}

G

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

题目描述

X腿与队友到河北省来参加2019河北省大学生程序设计竞赛,然而这场比赛的题目难度实在是太高了。比赛开始一个小时后,X腿仍然没有做出一个题。这时候,X腿惊讶的发现电脑屏幕上出现了一个神奇按钮,按钮上写着”点我签到“。X腿非常兴奋,于是他点击了这个按钮,只见屏幕上的题目状态由“未提交”转变成了“答案错误”。他又点击了一下这个按钮,题目状态由“答案错误”变成了“通过”!

当题目状态为“通过”时,我们认为X腿签到成功了。

通过多次实验,X腿总结出以下经验:

当题目状态为”未提交“时,点击按钮后题目状态将变为”答案错误“。

当题目状态为”答案错误“时,点击按钮后题目状态将变为”通过“。

当题目状态为”*通过“时,点击按钮后题目状态将变为”答案错误“。

现在,已知初始的题目状态为”未提交“。由于X腿过于兴奋,点击了 n 次按钮。请问X腿签到成功了吗?

输入描述:

一行一个正整数 n,代表X腿点击了 n 次按钮。
0≤n≤1000000≤n≤100000

输出描述:

输出一行。如果X腿签到成功,请你输出“qiandaochenggong”;否则输出"qiandaoshibai”。(输出均不含引号)

示例1

输入

复制

3

输出

复制

qiandaoshibai

 题解:水题

#include<bits/stdc++.h>
using namespace std;
 
int main()
{
    int n;
    cin>>n;
    if(n==0){
        cout<<"qiandaoshibai"<<endl;
    }
    else{
        if(n%2==0){
            cout<<"qiandaochenggong"<<endl;
        }
        else{
            cout<<"qiandaoshibai"<<endl;
        }
    }
    return 0;
}

H

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

题目描述

2018年,icebound打开了神殿。而在2019年,icebound正在试图破解天神的密码,以期获得天神的力量。

icebound发现,想要得到神的密码,必须先要完成一个祭祀仪式。在这个祭祀仪式上,我们首先会追随神的指引,得到两个正整数 N和 K。随后,我们令 X=NKX=NK,得到天神喜欢的数字X。

利用 X,我们进行以下方式得到天神最后的密码:

步骤 1 将 X每个数位上的数字相加得到 Y。

步骤 2 令 X=Y

步骤 3 反复执行 步骤 1,直到 X只有一个数位时停止,即 1≤X≤91≤X≤9。此时的 X 即为天神的密码。

比如:当 N=11,K=2 时,首先我们得到 X=NK=112=121X=NK=112=121。然后我们把 X 的各个数位上的数相加,即 Y=1+2+1=4。此时 X=Y=4,X 仅有一个数位了,所以我们停止操作,得到天神的密码为4。

icebound许诺,如果他获得了天神的力量,一定保你荣华富贵,全家幸福,还会另外送你一块金牌。所以,请你帮助他计算天神的密码。

输入描述:

首先第一行一个整数 T ,代表数据组数。
随后 T 行,每行两个数 N,K ,用空格隔开。
1≤T≤201≤T≤20,1≤N≤1091≤N≤109,1≤K≤21≤K≤2

输出描述:

一行一个整数 X,表示天神的密码。

示例1

输入

复制

2
11 2
100 1

输出

复制

4
1

题解:水题 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        ll n,k;
        cin>>n>>k;
        ll x=k==2?n*n:n;
        while(x>9)
        {
            ll tm=0;
            while(x){
                tm+=x%10;
                x/=10;
            }
            x=tm;
        }
        cout<<x<<endl;
    }
 
 
    return 0;
}

K

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

题目描述

不知不觉当中,河北成为了一些人心中的“美食荒漠”,除了驴肉火烧,大抵想不起什么河北的美食了。大概是京津太过闪耀,盖过了冀菜的光芒。其实河北并不是美食荒漠,像邯郸的豆沫,石家庄的缸炉烧饼,唐山的酥糖,秦皇岛的皮皮虾,总能勾起心中最美好的回忆。

icebound最喜欢吃河北菜,于是他想要大厨做一桌河北菜宴请宾客。icebound购买了一些食材,并且制订了宴会的菜单。但是他并不知道这些食材是否足够,所以希望你写一个程序帮助他。
icebound将会给出每种食材的名称和数量,以及完整的菜单。菜单将包含每种菜品所需的食材及数量。菜单上的每道菜只需制作一次。

输入描述:

第一行给出两个整数 n , m,分别代表食材种类和菜品数量。
第 二 到第 n+1 行,每行一个由小写字母组成的字符串 sisi 和一个数字 aiai,表示这种食材的名称和数量。
接下来 m 行,每行首先有一个整数 k,代表这种菜品所需的食材种类数。
随后将会有 k 个字符串,代表食材名称,每个字符串后跟有一个数字 titi,用空格隔开,代表需要的食材数量。
1≤n,m≤10001≤n,m≤1000,1≤k≤101≤k≤10 且 k≤nk≤n
1≤ai,ti≤1091≤ai,ti≤109,1≤|si|≤201≤|si|≤20
保证输入合法,食材名称不会相同,且菜谱中不会有未出现的食材。

输出描述:

 

如果食材足够将菜单上的所有菜品全部制作一遍,请输出一行“YES”,并且按照输入顺序输出剩下的食材以及对应的数量,每行一个食材,用空格将食材和其数量隔开。如果某种食材全部被用完,则不输出该食材。

如果不能,输出一行“NO”。

示例1

输入

复制

5 3
water 100
flour 20
cabbage 71
pork 12
bean 5
2 water 20 flour 5
3 water 70 cabbage 54 pork 10
5 water 1 flour 1 cabbage 1 pork 2 bean 1

输出

复制

YES
water 9
flour 14
cabbage 16
bean 4

题解:水题

 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
map<string,int> menu;
vector<string>  vmenu;
int main()
{
    int n,m;
    while(cin>>n>>m)
    {
        string a;int b;
        while(n--)
        {
            cin>>a>>b;
            menu[a]=b;
            vmenu.emplace_back(a);
        }
        int flag=0;
        int k;
        while(m--)
        {
            cin>>k;
            while(k--)
            {
                cin>>a>>b;
                menu[a]-=b;
                if(menu[a]<0){flag=1;}
            }
        }
        if(flag==0)
        {
            cout<<"YES"<<endl;
            for(string i:vmenu)
            {
                if(menu[i]>0)
                cout<<i<<" "<<menu[i]<<endl;
            }
        }
        else
        {
            cout<<"NO"<<endl;
        }
    }
    return 0;
}

L

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

题目描述

Icebound dreams of being aLegendary grandmaster. So he built a smart robot to help him.

The robot works on a N*N matrix. All the numbers in the matrix are non-negative integers less than 10. The robot can move in the matrix. If it's in the (x,y) position of the matrix, it can move to (x+1,y) , (x,y+1), (x-1,y), (x,y-1), which are the adjacent positions of the robot. But the robot has to operate inside the matrix. It can't get out of the matrix.

The robot can start at any position in the matrix, take any step, and it can stop at any position in the matrix. We connect the numbers in the robot's path in order to get a magic number. For example, if the robot takes 3 steps and passes through 3 numbers of the matrix, 0,7 and 8, the magic number is 78.All the magic numbers are non-negative integers, and the number generated by the robot does not contain leading 0.

Through the robot, icebound got a lot of magic numbers. Now he wants to know what isthe smallest magic number he can't get.

输入描述:

The first line is an integer N, denoting the length and width of the matrix.
The next N lines, N numbers per line, separated by spaces, represent this matrix. Ensure that each number in the matrix is less than 10 and greater than or equal to zero.
The numbers in the matrix are randomly generated.
1≤N≤501≤N≤50

输出描述:

One integer per line, indicating the smallest magic number that icebound can not get.

示例1

输入

复制

4
1 2 3 4
3 6 7 8
0 1 5 4 
9 1 1 1

输出

复制

17

题解:暴力跑深度为6的数组,然后从小到大判断没有出现的数字就打印输出。

#include<bits/stdc++.h>
using namespace std;
#define clr(a,b) memset(a,b,sizeof(a))
int n,matrix[55][55],vis[1000000];
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
void dfs(int deep,int ans,int x,int y)
{
    if(deep==0){return ;}
    for(int i=0;i<4;++i)
    {
        int nx=x+dx[i];
        int ny=y+dy[i];
        if(nx<1||nx>n){continue;}
        if(ny<1||ny>n){continue;}
        int tans=ans*10+matrix[nx][ny];
        vis[tans]=1;
        dfs(deep-1,tans,nx,ny);
    }
    return ;
}
void solve()
{
    for(int i=1;i<=n;++i)
    for(int j=1;j<=n;++j)
    {
        dfs(5,matrix[i][j],i,j);
        vis[matrix[i][j]]=1;
    }
    return ;
}
int main()
{
    clr(matrix,0);
    clr(vis,0);
    cin>>n;
    for(int i=1;i<=n;++i)
    for(int j=1;j<=n;++j)
    {
        cin>>matrix[i][j];
    }
    solve();
    for(int i=0;;++i)
    {
        if(!vis[i]){cout<<i<<endl;break;}
    }
    return 0;
}

J:

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

题目描述

> “舔狗舔狗,
> 舔到最后,
> 一无所有。”

有 n 只舔狗,每只舔狗的心中都有自己朝思暮想的一位。

每个人虽然受到了一万次拒绝,还毅然第一万零一次鼓起勇气。

作为一个不食人间烟火的算法设计师,你早已看破红尘。但是,人世间的苦难仍让你挂念。看到众生在单恋中苦苦坚持,你决定普度众生,给大家找到一个最好的结局,让一无所有的舔狗尽量地少,让每个人都尽量能和自己喜欢的或喜欢自己的人修成正果。

也就是说,你需要给这 n 只舔狗配对,对于舔狗 i,他可以和他朝思暮想的人 aiai 配对。另外,喜欢 i 的其他舔狗也可以和他配对。你需要让没有被配对的舔狗尽量少。

输入描述:

第一行一个 n,表示舔狗个数。
第二行 n 个数字,第 i 个数字表示第 i只舔狗的朝思暮想的一位的编号 aiai。
2≤n≤1062≤n≤106

输出描述:

第一行一个数字,表示一无所有的舔狗的最小数量。

示例1

输入

复制

10
3 1 8 6 10 1 4 1 6 1

输出

复制

0

题解:被喜欢的设为入度 ,每次选择入度最小的给分配(哈哈哈哈),然后将喜欢的喜欢的人入度减一。这样说来同性也是可以的么哈哈。

#include<bits/stdc++.h>
using namespace std;
#define clr(a,b) memset(a,b,sizeof(a))
typedef long long ll;
//贪心优先考虑没有入度的点
const int maxn=1000000+2;
struct Edge
{
    int now;
    int in;//入度
    Edge(){}
    Edge(int now,int in):now(now),in(in){}
    bool operator <(const Edge &a)const{
    return in>a.in;
    }
}edge[maxn];
int n,to[maxn],vis[maxn];
void bfs()
{
    clr(vis,0);
    priority_queue<Edge> qu;
    for(int i=1;i<=n;++i){qu.emplace(edge[i]);}
    while(!qu.empty())
    {
        Edge t=qu.top();qu.pop();
        if(vis[t.now]||vis[to[t.now]]){continue;}
         vis[t.now]=vis[to[t.now]]=1;
         n-=2;
         int tm=to[to[t.now]];
         qu.emplace(Edge(edge[tm].now,--edge[tm].in));
    }
    cout<<n<<endl;
    return ;
}
int main()
{
    cin>>n;
    clr(edge,0);clr(to,0);
    for(int i=1;i<=n;++i)
    {
        cin>>to[i];
        edge[i].now=i;
        edge[to[i]].in++;
    }
    bfs();
    return  0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值