【无标题】

一、特殊的正方形

1.题目

输入n,输出n行n列的由+和.组成的正方形,其中最外面一圈全是+,第二圈全是.,…,对于第i圈,如果i是奇数,那么全是+,否则全是.。

输入格式
一行,一个整数n。

输出格式
n行,为满足题目要求的正方形。注意不要有行末空格。

2.样例

输入

10

输出

++++++++++
+........+
+.++++++.+
+.+....+.+
+.+.++.+.+
+.+.++.+.+
+.+....+.+
+.++++++.+
+........+
++++++++++

3.思路

先解决1/4的图形,剩下的找关系就行

4.代码

#include<bits/stdc++.h>
using namespace std;
int n;
int main(){
	cin>>n;
	char a[1000][1000];
	for(int i=1;i<=(n+1)/2;i++){
			if(i%2==0){
			for(int k=1;k<=i;k++)
				if(k%2==0)
				a[i][k]=a[n-i+1][k]=a[i][n-k+1]=a[n-i+1][n-k+1]='.';
				else 
				a[i][k]=a[n-i+1][k]=a[i][n-k+1]=a[n-i+1][n-k+1]='+';
				for(int j=i+1;j<=(n+1)/2;j++)
				a[i][j]=a[i][n-j+1]=a[n-i+1][j]=a[n-i+1][n-j+1]='.';	
			}
			else{
				for(int k=1;k<=i;k++)
				if(k%2==0)
				a[i][k]=a[n-i+1][k]=a[i][n-k+1]=a[n-i+1][n-k+1]='.';
				else 
				a[i][k]=a[n-i+1][k]=a[i][n-k+1]=a[n-i+1][n-k+1]='+';
				for(int j=i+1;j<=(n+1)/2;j++)
				a[i][j]=a[i][n-j+1]=a[n-i+1][j]=a[n-i+1][n-j+1]='+';
			}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++)
		cout<<a[i][j];
		cout<<endl;
	}
}

二、走楼梯2

1.题目

楼梯有 n阶,上楼可以一步上一阶,也可以一步上二阶。
但你不能连续三步都走两阶,计算走到第n阶共有多少种不同的走法。
输入格式
一行,一个数字,表示n。
输出格式
输出走楼梯的方式总数。

2.样例

输入

6

输出

12

3.思路

f[n][3],其中f[i][0]表示i层前多少个有0个2步,f[i][1]表示i层前多少个有1个2步,f[i][1]表示i层前多少个有2个2步.

4.代码

#include<bits/stdc++.h>
using namespace std;
long long int n,f[51][3];
int main(){
	cin>>n;
	f[1][0]=1,f[2][1]=1,f[2][0]=1;
	for(int i=3;i<=n;i++){
		f[i][0]=f[i-1][0]+f[i-1][1]+f[i-1][2];
		f[i][1]=f[i-2][0];
		f[i][2]=f[i-2][1];
	}
	cout<<f[n][0]+f[n][1]+f[n][2];
}

三、

1.题目

有一条很长的数轴,一开始你在0的位置。接下来你要走n步,第i步你可以往右走ai或者bi。
问n步之后,0到m的每个位置,能不能走到?
输入格式
第一行,两个整数n,m。

接下来n行,每行两个整数ai,bi。

输出格式
一行,一共m+1
个数,每个数都是0或1表示能否走到,数字之间不用空格隔开。

2.样例

输入

3 10
1 2
2 6
3 3

输出

00000011001

3.思路

第i步到哪就用f[x]存储i+1,最后将值为n+1的输出为1,其它的为0

4.代码

#include<bits/stdc++.h>
using namespace std;
int n,m,a[100001],b[100001],f[110001],g[110001];
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	cin>>a[i]>>b[i];
	int s1,s2;
	g[0]=1,f[0]=1;
	for(int i=1;i<=n;i++){
		for(int j=0;j<=m;j++){
			if(f[j]==i)
				g[j+a[i]]=i+1,g[j+b[i]]=i+1;
		}
		for(int j=0;j<=m;j++)
		f[j]=g[j];
	}
	for(int i=0;i<=m;i++)
	if(f[i]==n+1)
	cout<<1;
	else cout<<0;
}

四、

1.题目

N 个好朋友在codeforces上参加一场包含 M个题目的比赛, 比赛期间codeforces网站一共有 k 次提交。
已知每个题目的分数,但是由于他们只能查到在比赛期间codeforces总共的提交记录(其他用户提交的其他题目记录也包含在内, 即存在不属于该场比赛的题目),
所以想请你编写一个程序算出他们每个人的分数。
输入格式
第一行三个整数 N, M, K 分别表示好朋友的个数, 题目的个数, 和提交的总次数(其中0<N,M,K<=200)。
接下来 N 行 第 i 行输入为第 i个人的id,
接下来 M行 第 j 行输入为第 j个题目的名称和分数,
接下来 K 行 第 k行输入为第 k次提交的提交者id, 题目名称和结果(“WA” 或 “AC”, 如果"AC"代表通过这个题目, 提交者获得对应分数)。

注: 题目名称和id均为仅包含英文字母和数字的字符串, 题目分数为小于等于 1e6
的正整数. 每一行的多个输入之间用空格隔开。

所有输入的字符串长度 length
满足 0<length≤500

所有用户id和题目名称不存在重名, 用户AC了某个题之后之后不会再重复提交该题, 好朋友们只会提交属于比赛的题目。

输出格式

2.样例

输入

2 2 4
GabrielPessoa
beza
metebronca 100
geometry 200
beza metebronca AC
ffern numbertheory AC
GabrielPessoa geometry WA
beza geometry AC

输出

GabrielPessoa 0
beza 300

3.思路

map快速解决

4.代码

#include<bits/stdc++.h>
using namespace std;
int n,m,k;
map<string,int>mp;
map<string,int>score;
string s[1000];
int main(){
	cin>>n>>m>>k;
	for(int i=1;i<=n;i++)
	cin>>s[i];
	for(int i=1;i<=m;i++){
		string ss;int re;
		cin>>ss>>re;
		mp[ss]=re;
	}
	for(int i=1;i<=k;i++){
		string s1,s2,s3;
		cin>>s1>>s2>>s3;
		if(s3=="AC"){
			score[s1]+=mp[s2];
		}
	}
	for(int i=1;i<=n;i++)
	cout<<s[i]<<" "<<score[s[i]]<<endl;
}

五、Alice的德州扑克

1.题目

德州扑克是目前世界上最流行的扑克游戏,全世界有众多相关的比赛,例如是 WSOP,WPT,EPT等,也让这款游戏的玩法变得层出不穷,丰富多变。 不要被简单的游戏规则而误导,复杂多变的比赛状况,让这款游戏在高水平的竞技中会变得非常复杂,这也让人们为德州扑克给出了这样一句评价 ”用一刻就能学会,但要用一生才能掌握” 。

现在我们并不在乎游戏规则是什么,因为 Alice 是一个德州扑克高手,他对于德州扑克的规则烂熟于心,不过他每次都记不得牌型的大小关系,他知道你是一个编程高手,所以他想让你帮他写一个程序:输入五张牌的大小和花色,输出这五张牌能组成的最大牌型.你能帮帮他吗?

为了降低你的编程难度,我们规定:

输入的牌都是来源于同一副扑克牌

输入的牌的点数都是非递减的

所有花色没有大小之分

下面给出各牌型,(从大到小)

皇家同花顺(ROYAL FLUSH):五张顺连的牌(点数连续单调递增),且最大的一张牌是A(Ace),并且五张牌的花色相同

同花顺(STRAIGHT FLUSH):五张顺连的牌(点数连续单调递增),不规定最大的一张牌是A(Ace),并且五张牌的花色相同

四条(FOUR OF A KIND):至少四张牌的点数相同

葫芦(FULL HOUSE):至少三张牌的点数相同,并且除此之外还有两张牌的点数相同

同花(FLUSH):五张牌的花色都相同

顺子(STRAIGHT):五张顺连的牌(点数连续单调递增),不要求五张牌的花色相同

特别注意:由于 Alice 是个谨慎的人,所以比 三条(THREE OF A KIND) (包括三条) 小的牌型 Alice 不在乎他们的大小关系,你只需要告诉 Alice 弃牌就行

输入格式
输入两行,每行五个数字,第一行的第 i
个字符表示第 i
张扑克的点数,

第二行的第 i
个数字表示第 i
张扑克花色。(保证输入的牌的点数是非递减的,且所有输入均合法)。

点数和对应输入的数字:

2−10
对应 2 - 10
J(Jack)
对应 11
Q(Queen)
对应 12
K(King)
对应 13
A(Ace)
对应 14
花色和对应输入的数字:

黑桃 (Spades) 对应 1
方片 (Diamonds) 对应 2
红桃 (Hearts) 对应 3
梅花 (Clubs) 对应 4
输出格式
输出这五张牌能组成的最大牌型。

如果最大是皇家同花顺输出 “ROYAL FLUSH”
如果最大是同花顺输出 “STRAIGHT FLUSH”
如果最大是四条输出 “FOUR OF A KIND”
如果最大是葫芦输出 “FULL HOUSE”
如果最大是同花输出 “FLUSH”
如果最大是顺子输出 “STRAIGHT”
如果最大的牌型小于等于三条输出"FOLD",劝 Alice 弃牌
输出不包括引号

2.样例

输入

10 11 12 13 14
1 1 1 1 1

输出

ROYAL FLUSH

3.思路

简单列举情况即可

4.代码

#include<bits/stdc++.h>
using namespace std;
int a[6],b[6];
bool sb(int i,int j){
	if(b[i]==b[j])
	return 1;
	else return 0;
}
bool ad(int i,int j){
	if(a[i]+1==a[j])
	return 1;
	else return 0;
}
bool sa(int i,int j){
	if(a[i]==a[j])
	return 1;
	else return 0;
}
int main(){
	for(int i=1;i<=5;i++)
	cin>>a[i];
	for(int i=1;i<=5;i++)
	cin>>b[i];
	if(sb(1,2)&&sb(1,3)&&sb(1,4)&&sb(1,5)){
		if(ad(1,2)&&ad(2,3)&&ad(3,4)&&ad(4,5)){
		if(a[5]==14){
			cout<<"ROYAL FLUSH";
			return 0;
		}else{
			cout<<"STRAIGHT FLUSH";
			return 0;
		}	
		}
	}
	if((sa(1,2)&&sa(1,3))||(sa(2,3)&&sa(2,4))||(sa(3,4)&&sa(3,5))){
	if(sa(1,4)||sa(2,5)){
		cout<<"FOUR OF A KIND";
		return 0;
	}else{
		cout<<"FULL HOUSE";
		return 0;
	}	
	}
	if(sb(1,2)&&sb(1,3)&&sb(1,4)&&sb(1,5)){
		cout<<"FLUSH";
		return 0;
	}
	if(ad(1,2)&&ad(2,3)&&ad(3,4)&&ad(4,5)){
		cout<<"STRAIGHT";
		return 0;
	}
	cout<<"FOLD";
	return 0;
}

六、订单编号

1.题目

小缘开了一家公司,生意很好,每天都会收到很多订单,自动交易系统会自动给这些订单生成没有重复的订单编号。但是有一天,系统出现了未知的错误,导致当天的订单编号可能有重复的,这可把小缘急坏了。你可以帮助小缘按照规则给这些订单重新编号吗?

按照时间先后顺序给出 N
个正整数作为原订单编号,你需要按照规则依次赋予这些订单新的编号,对于任意一个订单,要找到大于等于其原订单编号且未被使用过的(没有被之前的订单作为新的订单编号)的最小整数,作为它的新订单编号。

例如: 原订单编号依次为1 2 3 1,则新订单编号应该为1 2 3 4 (前3个订单的原订单编号都没有使用过,所以用其原订单编号即可,对于第四个订单,原订单编号为1,而1, 2, 3都已经被使用过,所以新订单编号为4)。

输入格式
第一行输入一个整数 N
(1≤N≤5×105)

第二行输入 N
个数 ai
(1≤ai≤109)
作为原订单编号。

输出格式
输出一行,包含 N
个整数为新的订单编号。

2.样例

输入

6
2 3 4 1 1 1

输出

2 3 4 1 5 6

4.代码

#include<bits/stdc++.h>
using namespace std;

int n;
set<pair<int, int>> s;

int main()
{
    s.insert(make_pair(2e9, 1)); // r,l
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
    {
        int x;
        scanf("%d", &x);
        auto itr = s.lower_bound(make_pair(x, 0));
        if (itr->second <= x)
        {
            printf("%d ", x);
            if (itr->first >= x + 1)
                s.insert(make_pair(itr->first, x + 1));
            if (x - 1 >= itr->second)
                s.insert(make_pair(x - 1, itr->second));
            s.erase(itr);
        }
        else
        {
            printf("%d ", itr->second);
            if (itr->first >= itr->second + 1)
                s.insert(make_pair(itr->first, itr->second + 1));
            s.erase(itr);
        }
    }
    return 0;
}

七、饿饿 饭饭

1.题目

有n个同学正在排队打饭,第i个同学排在从前往后第i个位置。但是这天食堂内只有一个食堂阿姨,为了使同学们都能尽快的吃上饭,每一个同学在打完一份饭之后就会排在队伍的末尾先吃着打到的饭,我们知道第i个同学的饭量为ai,也就是说第i个同学要吃ai份饭才能吃饱,当一位同学吃饱后,他就会立刻离开食堂,不会排在队伍的末尾。食堂阿姨想知道,在打完k份饭之后,队伍的样子是怎样的,但是食堂阿姨数学不太好,想让你帮忙想想办法。

输入格式
第一行给出两个整数n,k。

第二行给出n
个整数a1,a2,…an。

输出格式
如果食堂阿姨打饭数少于k,请输出"-1"。

否则按照队伍顺序输出每一个同学的编号。

2.样例

输入

3 3
1 2 1

输出

2

3.思路

利用二分查找找到值为多少是能到最后一轮,再进行进一步处理

4.代码

#include<bits/stdc++.h>
using namespace std;
int n,a[100001],b[100001];
long long k,sum;
int serch(int m){
	long long summ=0;
	for(int i=1;i<=n;i++){
		if(m>=a[i]) summ+=a[i];
		else summ+=m;
	}
	if(summ<=k) return 1;
	else return 0;
}
int main(){
	cin>>n>>k;
	for(int i=1;i<=n;i++) cin>>a[i],sum+=a[i];
	if(sum<k){
		cout<<-1;
		return 0;
	}
	int l=1,r=1e9,mid;
	while(l<=r){
		mid=(l+r)/2;
		if(serch(mid)) l=mid+1;
		else r=mid-1;
	}
	long long summ=0;
	int s=0;
	for(int i=1;i<=n;i++){
		if(r>=a[i]) summ+=a[i],a[i]=0;
		else a[i]-=r,summ+=r,b[++s]=i;
	}
	long long res=k-summ;
	for(int i=res+1;i<=s;i++)
	cout<<b[i]<<" ";
	for(int i=1;i<=res;i++)
	if(a[b[i]]>1) cout<<b[i]<<" ";
}

八、任务分配

1.题目

你有n个任务,其中第i个任务,在si开始,ei时刻结束,如果做这个任务,你能获得wi的收益。

但是你在一个时刻只能做一个任务,问选择哪些任务,能让你的收益尽量大。

注意:你在上一个任务结束后马上开始下一个任务是可以的。

输入格式
第一行一个整数n。

接下来n行,每行三个整数si,ei,wi。

输出格式
一个数,表示答案。

2.样例

输入

3
1 3 100
2 4 199
3 5 100

输出

200

3.思路

每次f[i]为到i时,最大收益。它可以为f[i-1]和f[i]最大值,进行循环以i为开始点对后面进行替换

4.代码

#include<bits/stdc++.h>
using namespace std;
int n,s[1100],e[1100],w[1100],f[1100]; 
int main(){
	cin>>n;
	for(int i=1;i<=n;i++)
	cin>>s[i]>>e[i]>>w[i];
	for(int i=1;i<=1000;i++){
		f[i]=max(f[i],f[i-1]);
		for(int j=1;j<=n;j++){
		if(s[j]==i){
			f[e[j]]=max(f[e[j]],f[i]+w[j]);
		}	
		}
	}
	cout<<f[1000];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

木易·

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

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

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

打赏作者

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

抵扣说明:

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

余额充值