2024牛客五一集训派对day1

B. Coffee Chicken

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题目描述

Dr. JYY has just created the Coffee Chicken strings, denoted as S(n). They are quite similar to the Fibonacci soup --- today's soup is made by mingling yesterday's soup and the day before yesterday's soup:
- S(1)="COFFEE"S(1) = \texttt{"COFFEE"}S(1)="COFFEE";
- S(2)="CHICKEN"S(2) = \texttt{"CHICKEN"}S(2)="CHICKEN";
- S(n) = S(n-2) :: S(n-1), where :: denotes string concatenation.
The length of S(n) quickly gets out of control as n increases, and there would be no enough memory in JYY's game console to store the entire string. He wants you to find 10 contiguous characters in S(n), starting from the kth character.

输入描述:

The first line of input is a single integer T (1≤T≤1000)(1 \leq T \leq 1000)(1≤T≤1000), denoting the number of test cases. Each of the following T lines is a test case, which contains two integers n, k (1≤n≤500,1≤k≤min⁡{∣S(n)∣,1012})(1 \leq n \leq 500, 1 \leq k \leq \min\{|S(n)|, 10^{12}\})(1≤n≤500,1≤k≤min{∣S(n)∣,1012}). |S| denotes the length of string S.

输出描述:

For each test case, print the answer in one line. If there are no enough characters from the kth character, output all characters until the end of the string.

示例1

输入

复制2 3 4 2 7

2
3 4
2 7

输出

复制FEECHICKEN N

FEECHICKEN
N

思路:这题其实就是一个斐波那契数列的延申,和队友研究了一阵子怎么减少时间复杂度,怎么减枝优化字串长度,其实直接根本不需要去计算字串长度,更不用去记录字串是什么,内存会炸,所以就是采用递归或者迭代的思想,这里队长和我想到一起去了,下面是队长和我的代码(队长的是前者) 

主要的思路就是将每个字串分成两部分,也就是f(n- 1)和f(n - 2)这两部分,然后看k在哪个区间内,一直往前找,其中的f(n - 1)等也是按照同样的方法向前找,直到找到第一或者第二个字串就结束(因为所有的字符都是从这里传出去的,当然能从这两个字串里面找出来)

然后10个字符或者比这少的字符直接按照和k一样进行计算就行了,需要注意的是,最好把int换成long long 队长和我都是卡了这个,其实改了就可以全过了。其实我这里用的是dp,主要是想到这个问题很dp,就是子问题之间有依赖关系,然后可以列状态转移方程,(最优子结构(问题的最优解可以由其子问题的最优解来构造),然后还有子问题重叠)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll N=1e12+10;
ll num[505];
char s[2][20]={"COFFEE","CHICKEN"};
void f(){
	num[1]=6,num[2]=7;
	for(int i=3;i<=60;i++){
		num[i]=min(num[i-2]+num[i-1],N);
	}
}

void findd(int n,ll kk){
	if (n==1) cout<<s[0][kk-1];
	else if (n==2) cout<<s[1][kk-1];
	else{
		if (kk>num[n-2]) findd(n-1,kk-num[n-2]);
		else findd(n-2,kk);
	}
}

int main() {
	f();
	ll time,n,k;
	cin>>time;
	while(time--){
		cin>>n>>k;
		if (n>=58){
			if (n%2==0) n=56;
			else n=57;
		}
		for(ll i=k;i<min(num[n]+1,k+10);i++){
			findd(n,i);
			
		}
		cout<<endl;
	}
	
	return 0;
}

 

#include "bits/stdc++.h"
using namespace std;
typedef pair<double, double> PII;
typedef long long ll;
PII dp[600];
int main(){
    int n;
    cin>>n;
    long long  a;
    double  b;
    string s[4];
    s[1] = "COFFEE";
    s[2] = "CHICKEN";
    dp[1].first = 0;
    dp[2].first = 0;
    dp[1].second = 6;
    dp[2].second = 7;
    for(int i = 3; i <= 500; i ++){
        dp[i].first = dp[i - 2].second ;
        dp[i].second = dp[i - 2].second + dp[i - 1].second;
    }
    while(n --){
        cin>>a>>b;
        ll aa = a, bb = b;
        int end = -1;
        if(10  > dp[a].second - b + 1) end = dp[a].second - b+ 1;
        if(end != -1) end = min(end, 10);
        else end = 10;
        string s1 = "";
        for(ll i = b; i < b + end; i ++){
                a = aa;
                ll t = i;
                while(a >= 3){
                if(t > dp[a].first)  t = t - dp[a].first, a = a - 1 ;
                else a = a - 2;
                
            }
            s1 += s[a][t - 1];
            
        }    
        cout<<s1;

        if(n != 0) cout<<endl;
    }
    
    return 0;
}

 F. Popping Balloons

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

时间限制:C/C++ 5秒,其他语言10秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld

题目描述

Recently, an interesting balloon-popping game can be commonly found near the streets. The rule of this game is quite simple: some balloons are tied to cells of a lattice, and you are allowed to throw some darts to prick the balloons. The more balloons you pierce, the more incredible prize you will get.

Probably because too many people have got bored with this childish game, a new variation of the game has appeared. In this variation, you should prick the balloons by shooting an air rifle instead of throwing darts. You can make six shots in total, three horizontally and three vertically. If you shoot horizontally (vertically, resp.), all balloons in the row (column, resp.) are popped. In order to increase the difficulty, there is one restriction imposed on your shots: the distances between any two adjacent horizontal shots and any two adjacent vertical shots must all equal to a given number rrr. The problem is, what is the maximum number of balloons you can pop by making three horizontal and three vertical shots, under the aforementioned restriction.

输入描述:

The first line of input is two integers n, r (1≤n,r≤105)(1 \leq n, r \leq 10^5)(1≤n,r≤105), the number of balloons and the distance between any two adjacent horizontal or vertical shots.

The remaining part of the input is n lines, specifying the positions of the balloons. Each of these lines contains two integers x, y (0≤x,y≤105)(0 \leq x, y \leq 10^5)(0≤x,y≤105), denoting a balloon positioned at (x, y). Note that multiple balloons may lie in the same position.

输出描述:

Output the answer as a single integer in one line.

示例1

输入

复制7 1 0 0 1 1 2 2 3 3 4 4 5 5 7 8

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

输出

复制6

6

示例2

输入

复制5 2 0 10 2 3 5 7 9 6 2 3

5 2
0 10
2 3
5 7
9 6
2 3

输出

复制4

4

思路:

这道题借鉴了大佬的思路,比较清晰,主要就是暴力枚举每种可能,因为题目给的时间很长,所以直接尝试,然后首先找边界,缩小时间,然后统计每一行每一列的分数,然后求出每隔r行(列) 的所有的分数的可能,进行排列,找最大的前六组(行列都是),各选三组进行求和,然后进行比较(记得减去中间重叠部分),就是我们需要的答案。

#include "bits/stdc++.h"
using namespace std;
const int N = 1e5 + 100;
struct HL{
	int id, num;
}a[N], b[N];
bool cmp(HL x, HL y){
	return x.num > y.num;
}
map<int, map<int, int> > mp;
int row[N], col[N];
int main(){
// 	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);

	int n, r, x, y, ans = 0;
	
	scanf("%d%d",&n,&r);
	int maxx = 0, maxy = 0;
	int minx= 1e6, miny = 1e6;
	for(int i = 0; i < n; i ++){
		
	scanf("%d%d",&x,&y);
		minx = min(minx, x);
		miny = min(miny, y);
		maxx = max(maxx, x);
		maxy = max(maxy, y); 
		mp[x][y]++;
		col[x] ++;
		row[y] ++;
//		a[i].id = i;
//		a[i].num += 
	}
	for(int i =minx; i <= maxx; i ++){
		a[i].id = i;
		a[i].num = col[i];
		if(i + r <= maxx) a[i].num += col[i + r];
		if(i - r >= minx) a[i].num += col[i - r];
		
	}
	sort(a + minx, a + maxx, cmp);
	for(int i = miny; i <= maxy; i ++){
		b[i].id = i;
		b[i].num = row[i];
		if(i + r <= maxy) b[i].num += row[i + r];
		if(i - r >= miny) b[i].num += row[i - r];
			
	}
	sort(b + miny, b + maxy, cmp);
	for(int i = minx; i <= minx + 5; i ++){
		for(int j = miny; j <= miny + 5; j ++){
			int temp = a[i].num + b[j].num;
			int xx = a[i].id, yy = b[j].id;
			temp -= mp[xx][yy] + mp[xx][yy - r] + mp[xx][yy + r];
			temp -= mp[xx + r][yy] + mp[xx + r][yy + r] + mp[xx + r][yy - r];
			temp -= mp[xx - r][yy] + mp[xx - r][yy + r] + mp[xx - r][yy - r];
			ans = max(ans, temp);
			
		}
	}

	printf("%d\n",ans);
	return 0;
}

 

 链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

时间限制:C/C++ 5秒,其他语言10秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld

题目描述

Recently, an interesting balloon-popping game can be commonly found near the streets. The rule of this game is quite simple: some balloons are tied to cells of a lattice, and you are allowed to throw some darts to prick the balloons. The more balloons you pierce, the more incredible prize you will get.

Probably because too many people have got bored with this childish game, a new variation of the game has appeared. In this variation, you should prick the balloons by shooting an air rifle instead of throwing darts. You can make six shots in total, three horizontally and three vertically. If you shoot horizontally (vertically, resp.), all balloons in the row (column, resp.) are popped. In order to increase the difficulty, there is one restriction imposed on your shots: the distances between any two adjacent horizontal shots and any two adjacent vertical shots must all equal to a given number rrr. The problem is, what is the maximum number of balloons you can pop by making three horizontal and three vertical shots, under the aforementioned restriction.

输入描述:

The first line of input is two integers n, r (1≤n,r≤105)(1 \leq n, r \leq 10^5)(1≤n,r≤105), the number of balloons and the distance between any two adjacent horizontal or vertical shots.

The remaining part of the input is n lines, specifying the positions of the balloons. Each of these lines contains two integers x, y (0≤x,y≤105)(0 \leq x, y \leq 10^5)(0≤x,y≤105), denoting a balloon positioned at (x, y). Note that multiple balloons may lie in the same position.

输出描述:

Output the answer as a single integer in one line.

示例1

输入

复制7 1 0 0 1 1 2 2 3 3 4 4 5 5 7 8

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

输出

复制6

6

示例2

输入

复制5 2 0 10 2 3 5 7 9 6 2 3

5 2
0 10
2 3
5 7
9 6
2 3

输出

复制4

4

 

 思路,这道题目其实就是一道水题,直接用vector数组进行存边,然后发现每一个形状都或多或少的边的情况不一样,由于形状很少,所以可以直接进行判断。这里我使用了一个s数组,用来存每一个图形的边的数量,s的下标表示某点连接的边数(出度或者入度),值就表示有几个点,比如s[i] = x; 就是有i条边的点有x个。

#include "bits/stdc++.h"
#include "string.h"
using namespace std;
vector<int> v[7];
int s[20];
int main(){
	int n;
	cin>>n;
	while(n--){
		for(int i = 1; i <= 6; i ++) v[i].clear();
		memset(s, 0, sizeof(s));
		int flag = -1;
		int a, b;
		int ans1 = 0, ans2 = 0;
		for(int i = 0; i < 5; i ++){
			cin>>a>>b;
			v[a].push_back(b);
			v[b].push_back(a);
		}
		for(int i = 1; i <= 6; i ++){
			s[v[i].size()] ++;
			if(v[i].size() == 3){
				flag = i;
			}
		}
		for(int i = 1; i <= 4; i ++){
			if(i == 3 && s[i] == 1){
				if(flag != -1){
					for(int j = 0; j <v[flag].size(); j ++){
						if(v[v[flag][j]].size() == 1) ans1 ++;
						else ans2 ++;
					}
				}
				break;	
			}
			
		}
		if(ans1 == 2) cout<<"2-methylpentane"<<endl;
		else if(ans1 == 1 && ans2 == 2) cout<<"3-methylpentane"<<endl;
		else if(s[1] == 4 && s[3] == 2) cout<<"2,3-dimethylbutane"<<endl;
		else if(s[4] == 1 ) cout<<"2,2-dimethylbutane"<<endl;
		else if(s[1] == 2 && s[2] == 4) cout<<"n-hexane"<<endl;
		
	}
	
	return 0;
} 

 

  • 55
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小竹子14

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值