代码源week1

第一题:

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

输入格式

一行,一个整数n�。

输出格式

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

样例输入

10

样例输出

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

数据范围

对于100%100%的数据,保证2≤n≤1002≤�≤100。

 

思路:

首先读取输入的整数n,然后使用两个嵌套循环遍历每个位置。

对于每个位置,判断它在正方形的哪一圈,

如果是最外面一圈或者行列为偶数,

则输出+,否则输出.,最后加上换行符以换行。 

AC代码:

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

int main()
{char a[105];string ans[105];
for(int k=0;k<105;k++)
a[k]='.';
int n;
cin>>n;
if(n%2==0)
{
int temp=n/2;int flag=0;
while(flag<temp)
{
	for(int i=flag;i<n-flag;i++)
	{
		if(a[i]=='.')
		a[i]='+';
		else a[i]='.';
		
	}
	
	for(int m= 0;m<n;m++)
	ans[flag]=ans[flag]+a[m];
	cout<<ans[flag]<<endl;
	flag++;
}


for(int qq=temp-1;qq>=0;qq--)
cout<<ans[qq]<<endl;
}



else 
{
	int temp=n/2+1;int flag=0;
	while(flag<temp)
	{
			for(int i=flag;i<n-flag;i++)
	{
		if(a[i]=='.')
		a[i]='+';
		else a[i]='.';
		
	}
	
	for(int m= 0;m<n;m++)
	ans[flag]=ans[flag]+a[m];
	cout<<ans[flag]<<endl;
	flag++;
	
	
	}
	
	
	
	for(int qq=temp-2;qq>=0;qq--)
cout<<ans[qq]<<endl;
}

}

第二题:

楼梯有 n� 阶,上楼可以一步上一阶,也可以一步上二阶。

但你不能连续三步都走两阶,计算走到第n�阶共有多少种不同的走法。

输入格式

一行,一个数字,表示n�。

输出格式

输出走楼梯的方式总数。

样例输入

6

样例输出

12

数据规模

本题:

本题是一道典型的动态规划问题。我们可以定义一个长度为 n 的数组 dp,其中 dp[i] 表示走到第 i 级台阶的不同走法数目。

显然,当 i = 1 时,dp[i] = 1;当 i = 2 时,dp[i] = 2;当 i = 3 时,dp[i] = 2,因为不能连续三步都走两阶。对于 i > 3,dp[i] 的计算方法为:

  • 如果前一步走了一阶,那么前两步必须走两阶,此时 dp[i] = dp[i-2];
  • 如果前一步走了两阶,那么前两步不能都走两阶,此时 dp[i] = dp[i-1] + dp[i-2]。

最后 dp[n] 就是走到第 n 级台阶的不同走法数目。

AC代码:

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

int main()
{
	
	int n;
	cin>>n;
	long long a[53][3]={0};
	a[2][0]=1;a[2][1]=1; a[2][2]=0;
	a[1][0]=1;
	a[1][1]=0;a[1][2]=0;
	 for (int i = 3; i <= n; i ++ )
	 {
	 	a[i][0]=a[i-1][0]+a[i-1][1]+a[i-1][2];
	 	a[i][1]=a[i-2][0];
	 	a[i][2]=a[i-2][1];
	 }
	cout<<a[n][0]+a[n][1]+a[n][2];
}

 

第三题:

有一条很长的数轴,一开始你在00的位置。接下来你要走n�步,第i�步你可以往右走ai��或者bi��。

问n�步之后,00到m�的每个位置,能不能走到?

输入格式

第一行,两个整数n,m�,�。

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

输出格式

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

输入样例

3 10
1 2
2 6
3 3

输出样例

00000011001

数据规模

对于所有数据,保证1≤n≤100,1≤m≤105,1≤ai,bi≤10001≤�≤100,1≤�≤105,1≤��,��≤1000。

 

思路:

这比较典型的动态规划问题,

具体来说,我们可以使用一个长度为 m+1 的数组 f,其中 f[i] 表示能否从 0 走到位置 i。初始时 f[0] = 1,表示一开始就在位置 0。

对于每一个位置 i遍历前面的每一个位置 j,如果能从 j 走到 i,即 j+a[k] 或者 j+b[k] 等于 i,

可以把能够到达 j 的状态继承到能够到达 i 的状态上,

即 f[i] = f[i] || f[j]。

最后 f[m] 就是走到位置 m 的状态。

#include <bits/stdc++.h>
using namespace std;
int anss[100005]={0};
int flag;
int n,m;
int step[105][2];
void han(int t,int time)
{   if(time>n)
     {
     	anss[t]=1;
     	return;
	 }
     
	else
	{
	
	int temp,t1,t2;
	temp=t;
  t1=temp+step[time][0];
  t2=temp+step[time][1];
  time++;
  han(t1,time);
  han(t2,time);
   }
	
	
}
int main()
{


cin>>n>>m;




for(int i=1;i<=n;i++)
{
	cin>>step[i][0]>>step[i][1];
	
}
han(0,1);

for(int i=0;i<=m;i++)
{
cout<<anss[i];
}






}

 

第四题:

N� 个好朋友在codeforces上参加一场包含 M� 个题目的比赛, 比赛期间codeforces网站一共有 k� 次提交。

已知每个题目的分数,

但是由于他们只能查到在比赛期间codeforces总共的提交记录(其他用户提交的其他题目记录也包含在内, 即存在不属于该场比赛的题目),

所以想请你编写一个程序算出他们每个人的分数。

输入格式

第一行三个整数 N�, M�, K� 分别表示好朋友的个数, 题目的个数, 和提交的总次数(其中0<N,M,K<=2000<�,�,�<=200)。

接下来 N� 行 第 i� 行输入为第 i� 个人的id,

接下来 M� 行 第 j� 行输入为第 j� 个题目的名称和分数,

接下来 K� 行 第 k� 行输入为第 k� 次提交的提交者id, 题目名称和结果("WA" 或 "AC", 如果"AC"代表通过这个题目, 提交者获得对应分数)。

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

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

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

输出格式

输出 N� 行, 第 i� 行输出第 i� 个人的名字和对应分数 (名字和分数用空格隔开)。

样例输入

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

样例解释

beza 过了 metebronca和geometry 拿到 300300 分。

GabrielPessos 没有过题, 所以是 00 分。

还有一些其他选手提交的其他题目忽略不计。

 中文 

 

 

 

  1. 将所有提交中属于比赛的记录筛选出来,

  2. 构建一个列表,包含每个提交者id,对应的题目名称和结果。

  3. 遍历每个人,统计其AC题目的得分,输出对应的名字和分数。

    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
    	
    	int n,m,k;
    	cin>>n>>m>>k;
    	pair<string,int> man[201];
    	pair<string,int> timu[201];
    	for(int i=0;i<n;i++)
    {cin>>man[i].first;
    
    man[i].second=0;
    	}	
    for(int i=0;i<m;i++)
    	cin>>timu[i].first>>timu[i].second;
    	
    	for(int i=0;i<k;i++)
    	{
    		
    	string name,ti,flag;
    	cin>>name>>ti>>flag;
    		for(int ii=0;ii<n;ii++)
    		{
    			if(name==man[ii].first&&flag=="AC")
    			
    			{
    				for(int iii=0;iii<m;iii++)
    				{
    					if(ti==timu[iii].first)
    					man[ii].second+=timu[iii].second;
    				}
    				
    			}
    		}
    	
    	}
    
    	
    	for(int i=0;i<n;i++)
    	cout<<man[i].first<<" "<<man[i].second<<endl;
    	
    	
    	
    	
    	
    	
    
    	
    	
    	
    	
    	
    	}
    

第五题:

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

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

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

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

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

  3. 所有花色没有大小之分

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

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

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

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

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

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

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

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

输入格式

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

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

点数和对应输入的数字:

  • 2−102−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 弃牌
  • 输出不包括引号

样例输入1

10 11 12 13 14
1 1 1 1 1

样例输出1

ROYAL FLUSH

样例输入2

10 11 12 13 14
1 2 1 3 4

样例输出2

STRAIGHT

样例输入3

6 6 6 7 7
1 2 3 1 3

样例输出3

FULL HOUSE

样例输入4

3 3 6 6 9
1 2 1 2 1

样例输出4

FOLD

 

思路:

模拟问题;

只需从大到小判断是否是相应花色即可

#include <bits/stdc++.h>
using namespace std;
int main()
{
	
int p[5];int flag=1;int tem,temp;
for(int i=0;i<5;i++)
{
cin>>p[i];
}
cin>>tem;

for(int i=0;i<4;i++)
{
cin>>temp;
if(temp!=tem)
flag=0;

}
	
	if(p[4]==14&&p[3]==13&&p[2]==12&&p[1]==11&&p[0]==10&&flag==1)
	cout<<"ROYAL FLUSH";
	else if(p[4]-p[3]==1&&p[3]-p[2]==1&&p[2]-p[1]==1&&p[1]-p[0]==1&&flag==1)
	cout<<"STRAIGHT FLUSH";
	else if(p[4]-p[3]==p[4]-p[2]&&p[4]-p[3]==p[4]-p[1]&&p[4]-p[3]==p[4]-p[0])
	cout<<"FOUR OF A KIND";
	else if(p[0]-p[4]==p[0]-p[3]&&p[0]-p[4]==p[0]-p[2]&&p[0]-p[4]==p[0]-p[1])
	cout<<"FOUR OF A KIND";
	
		else if((p[0]==p[1]&&p[0]==p[2]&&p[3]==p[4])||(p[0]==p[1]&&p[3]==p[2]&&p[3]==p[4]))
	cout<<"FULL HOUSE";
	else if(flag==1)
	cout<<"FLUSH";
	
	else if(p[4]-p[3]==1&&p[3]-p[2]==1&&p[2]-p[1]==1&&p[1]-p[0]==1)
	cout<<"STRAIGHT";
	
	else 
	cout<<"FOLD";
	
	
	
	
	
	
	
	
	
	
	
	
	
	}

 

第六题:

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

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

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

输入格式

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

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

输出格式

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

样例输入1

6
2 3 4 1 1 1

样例输出1

2 3 4 1 5 6

样例输入2

3
1000000000 1000000000 1000000000

样例输出2

1000000000 1000000001 1000000002

样例输入3

6
4 5 1 2 1 1

样例输出3

4 5 1 2 3 6

 

set用法
    set实质是集合
   set<类名>(系统类,自定义类,pair等)
利用set和pair组合,可以生成数轴区间

lowwer_bound(begin,end,number)找到区间中大于等于number的元素的地址 与 auto iter=  搭配


  upper_bound(begin,end,number)找到区间中大于number的元素的地址 与 auto iter=  搭配

 setname.lowwer_bound(number)  找到集合中大于等于number的元素的地址

make_pair(a,b)生成(a,b)的pair;

set的插入
      setname.insert(元素); 如果是多个用{},用逗号隔开

避免超时:
   ios_base::sync_with_stdio(false);
    cin.tie(NULL);
副作用:当设置为false时,cin就不能和scanf,sscanf, getchar, fgets等同时使用。

AC代码:

#include <bits/stdc++.h>
 
using namespace std;
 set<pair<int,int> >se;
 
void myinsert(int l,int r)
{
    if(r<l)return;
    se.insert({r,l});
}
 
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n;
    cin>>n;
    se.insert({2e9,1});
    rep(i,1,n)
    {
        int x;
        cin>>x;
        auto it=se.lower_bound({x,0});
        if(it->sec <=x)
        {
            cout<<x<<" ";
            myinsert(it->sec,x-1);
            myinsert(x+1,it->fir);
            se.erase(it);
        }
        else
        {
            cout<<it->sec<<" ";
            myinsert(it->sec+1,it->fir);
            se.erase(it);
        }
    }
    return 0;
}

第七题:

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

输入格式

第一行给出两个整数n�,k�。

第二行给出n�个整数a1,a2,......an�1,�2,......��。

输出格式

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

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

样例输入1

3 3
1 2 1

样例输出1

2

样例输入2

4 10
3 3 2 1

样例输出2

-1

样例输入3

7 10
1 3 3 1 2 3 1

样例输出3

6 2 3

数据规模

数据保证1≤n≤105, 0≤k≤1014, 1≤ai≤1091≤�≤105, 0≤�≤1014, 1≤��≤109。

 中文 

 

 

用一个map记录所有学生的饭量的出现次数,

map的自动排序功能,

使得小饭量的会排在前面。把

学生的饭量按照输入顺序存入数组中,同时记录所有饭量的总和,如果总和小于k,就直接输出-1。

开始模拟打饭,每次我们给全体喂当前打饭人中饭量最少的分量,我们直接从map中取出即可,喂完后,饭量最少的人就离开了队伍,我们要准备一个len来记录队伍剩余的人,

以此往复,当剩下的饭不够喂满最低饭量的人时结束循环,

我们遍历队伍,如果有没吃饱的人就给他一份饭,

然后他把存入另一个数组里(这个数组就充当队尾,

要注意,如果有人在此过程中吃饱了,就不存入数组里。

最后先输出队伍剩余的人,在输出队尾数组里的人

#include<bits/stdc++.h>
using namespace std;
set<int> diet;
int main()
{
	int n;
	long long  man[n+10];
	int ans[n+10],ans1[n+10];
	long long sum=0,k,jian;
	cin>>n>>k;
	for(int i=1;i<=n;i++)
	{
		cin>>man[i];
		diet.insert(man[i]);
		sum=sum+man[i];
		
	}
	
	if (sum<k)
	{
		cout<<-1;return 0;
	}
	else {
	
	int flag=0;int temp=0;
		
	
	
	
	for (auto it= diet.begin(); it != diet.end(); it++)
	{   jian=0;
		flag=*it-temp;
		temp=*it;
		
		for(int i=1;i<=n;i++)
		{
			if(man[i]!=0)
			{
				man[i]=man[i]-flag;
				jian=jian+flag;
			}
		}
		k=k-jian;
		
		
			for(int i=1;i<=n;i++)
			{
				sum=0;
			if(man[i]!=0)
			sum++;
			}
			
			
			
			
			
  	       if(sum>k);
	        break;
		
		
		
	}
	
	cout<<k<<endl;
	 int x=0; int x1=0;int tee;
	 
	for(int i=1;k>0;i++)
	{ 
	
		if(man[i]>1)
		{
			ans[x]=i;
			
			x++;
			k--;
		}
		
		else if(man[i]==1)
		{
		
			x1++;
			
			k--;
		}
		tee=i;
		
	}
	
	for(int i=tee+1;i<=n;i++)
	{
		if(man[i]>0)
		cout<<i<<" ";
	}
	
	
	
	
	
	for(int i=0;i<x;i++)
	{
		cout<<ans[i]<<" ";
	}
	
	

	
}
}

 第八题:

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

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

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

输入格式

第一行一个整数n�。

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

输出格式

一个数,表示答案。

样例输入

3
1 3 100
2 4 199
3 5 100

样例输出

200

数据规模

对于所有数据,保证1≤n≤103,1≤si<ei≤103,1≤wi≤1051≤�≤103,1≤��<��≤103,1≤��≤105。

 

任务只能在规定的时段开始

从最开始枚举时间。

遍历所有的任务,找到所有能从该时段开始执行的任务 

 设置dp数组f,f[i]为:当任务的结束时间为i时,所能获得的最大价值。

在接收数据时,按照任务的结束时间分类存储在v数组里

。同时记录一下所有任务中最大的结束时间。

#include<bits/stdc++.h>
using namespace std;
class ACT
{public:
	int b;
	int e;
	int v;
	
};
int main()
{
	int ans[1005]={0};
	ACT act[1005];
	int n;
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cin>>act[i].b>>act[i].e>>act[i].v;
	}
	
	
	ans[0]=0;
	for(int i = 1;i<=1000;i++)
	{
		ans[i] = max(ans[i],ans[i-1]);
		for(int j =0;j<n;j++)
		if(act[j].b==i)
		{
		ans[act[j].e]=max(ans[act[j].e],ans[i]+act[j].v);}
	}
	cout<<ans[1000];
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值