算法协会寒假训练Six

HDU1276:士兵队列训练问题(字符串是一个神助攻~)

某部队进行新兵队列训练,将新兵从一开始按顺序依次编号,并排成一行横队,训练的规则如下:从头开始一至二报数,凡报到二的出列,剩下的向小序号方向靠拢,再从头开始进行一至三报数,凡报到三的出列,剩下的向小序号方向靠拢,继续从头开始进行一至二报数。。。,以后从头开始轮流进行一至二报数、一至三报数直到剩下的人数不超过三人为止。

Input

本题有多个测试数据组,第一行为组数N,接着为N行新兵人数,新兵人数不超过5000。

Output

共有N行,分别对应输入的新兵人数,每行输出剩下的新兵最初的编号,编号之间有一个空格。

Sample Input

2
20
40

Sample Output

1 7 19
1 19 37

原解法:https://blog.csdn.net/qq_39825375/article/details/86765576   中的K题

#include<iostream>
#include<string>
using namespace std;
bool judge(string s) {
	int cnt=0;
	for(int i=0; i<s.size(); i++)
		if(s[i]=='+') cnt++;
	if(cnt<=3) return true;
	else return false;
}
int a[5];
int main() {
	int t,n;
	cin>>t;
	while(t--) {
		scanf("%d",&n);
		string s(n,'+');
		while(1) {
			if(judge(s)) break;
			int cnt2=0;
			for(int i=0; i<s.size(); i++) {
				if(s[i]=='+') {
					cnt2++;
					if(cnt2%2==0) s[i]='-';
				}
			}
			if(judge(s)) break;
			int cnt3=0;
			for(int i=0; i<s.size(); i++) {
				if(s[i]=='+') {
					cnt3++;
					if(cnt3%3==0) s[i]='-';
				}
			}
		}
		int cnt=0;
		for(int i=0; i<s.size(); i++) 
			if(s[i]=='+') 
				a[cnt++]=i+1;
		for(int i=0;i<cnt;i++){
			if(i) cout<<' ';
			cout<<a[i];
		}
		printf("\n");
	}
	return 0;
}

 

 

 HDU 1973 看病要排队(优先队列,规范格式)

看病要排队这个是地球人都知道的常识。
不过经过细心的0068的观察,他发现了医院里排队还是有讲究的。0068所去的医院有三个医生(汗,这么少)同时看病。而看病的人病情有轻重,所以不能根据简单的先来先服务的原则。所以医院对每种病情规定了10种不同的优先级。级别为10的优先权最高,级别为1的优先权最低。医生在看病时,则会在他的队伍里面选择一个优先权最高的人进行诊治。如果遇到两个优先权一样的病人的话,则选择最早来排队的病人。

现在就请你帮助医院模拟这个看病过程。

Input

输入数据包含多组测试,请处理到文件结束。
每组数据第一行有一个正整数N(0<N<2000)表示发生事件的数目。
接下来有N行分别表示发生的事件。
一共有两种事件:
1:"IN A B",表示有一个拥有优先级B的病人要求医生A诊治。(0<A<=3,0<B<=10)
2:"OUT A",表示医生A进行了一次诊治,诊治完毕后,病人出院。(0<A<=3)

Output

对于每个"OUT A"事件,请在一行里面输出被诊治人的编号ID。如果该事件时无病人需要诊治,则输出"EMPTY"。
诊治人的编号ID的定义为:在一组测试中,"IN A B"事件发生第K次时,进来的病人ID即为K。从1开始编号。

Sample Input

7
IN 1 1
IN 1 2
OUT 1
OUT 2
IN 2 1
OUT 2
OUT 1
2
IN 1 1
OUT 1

Sample Output

2
EMPTY
3
1
1
#include<iostream>
#include<string>
#include<queue>
using namespace std;
struct node{
	int pos,rate;
	bool operator<(const node &a)const{ //固定格式,只可用“<”
		if(rate!=a.rate) return rate<a.rate;
		return pos>a.pos;
	}
}p;
int main() {
	int n,a,b;
	string com;
	while(~scanf("%d",&n)){
		int id=1;
		priority_queue<node> q[4];
		while(n--){
			cin>>com>>a;
			if(com[0]=='I'){
				cin>>b;
				p.pos=id++, p.rate=b;
				q[a].push(p);
			}
			else if(com[0]=='O'){
				if(q[a].empty()) printf("EMPTY\n");
				else{
					p=q[a].top();
					q[a].pop();
					printf("%d\n",p.pos);
				} 
			}
		}
	}
	return 0;
}

 

 

 Codeforces-459A-Pashmak and Garden(情况考虑)

题意:给出两个点,判断是否存在两个点,使这四个点构成正方形

思路:已知两点只有四大类情况

  • 位于对角线
  • 位于同一列
  • 位于同一排
  • 无法构成正方形
#include<iostream>
#include<cmath>
using namespace std;
int main() {
	int x1,x2,y1,y2;
	scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
	if(abs(x1-x2)==abs(y1-y2))
		cout<<x1<<' '<<y2<<' '<<x2<<' '<<y1<<endl;
	else if(abs(x1-x2)==0){
		int tmp=abs(y1-y2);
		if(y1>y2) swap(y1,y2);
		cout<<x1+tmp<<' '<<y1<<' '<<x1+tmp<<' '<<y2<<endl;
	}
	else if(abs(y1-y2)==0){
		int tmp=abs(x1-x2);
		if(x1>x2) swap(x1,x2);
		cout<<x1<<' '<<y1+tmp<<' '<<x2<<' '<<y1+tmp<<endl;
	}
	else cout<<"-1\n";
	return 0;
}

 

 

 Frodo and pillows (review)

https://blog.csdn.net/qq_39825375/article/details/87118395 中的G题

 

 

 Candy Bags(review)

https://blog.csdn.net/qq_39825375/article/details/86685504 中的H题

 

 

 HDU 稳定排序(找排序后与乱序之区别)

 

大家都知道,快速排序是不稳定的排序方法。
如果对于数组中出现的任意a[i],a[j](i<j),其中a[i]==a[j],在进行排序以后a[i]一定出现在a[j]之前,则认为该排序是稳定的。

某高校招生办得到一份成绩列表,上面记录了考生名字和考生成绩。并且对其使用了某排序算法按成绩进行递减排序。现在请你判断一下该排序算法是否正确,如果正确的话,则判断该排序算法是否为稳定的。

Input

本题目包含多组输入,请处理到文件结束。
对于每组数据,第一行有一个正整数N(0<N<300),代表成绩列表中的考生数目。
接下来有N行,每一行有一个字符串代表考生名字(长度不超过50,仅包含'a'~'z'),和一个整数代表考生分数(小于500)。其中名字和成绩用一个空格隔开。
再接下来又有N行,是上述列表经过某排序算法以后生成的一个序列。格式同上。

Output

对于每组数据,如果算法是正确并且稳定的,就在一行里面输出"Right"。如果算法是正确的但不是稳定的,就在一行里面输出"Not Stable",并且在下面输出正确稳定排序的列表,格式同输入。如果该算法是错误的,就在一行里面输出"Error",并且在下面输出正确稳定排序的列表,格式同输入。

注意,本题目不考虑该排序算法是错误的,但结果是正确的这样的意外情况。

Sample Input

3
aa 10
bb 10
cc 20
cc 20
bb 10
aa 10
3
aa 10
bb 10
cc 20
cc 20
aa 10
bb 10
3
aa 10
bb 10
cc 20
aa 10
bb 10
cc 20

Sample Output

Not Stable
cc 20
aa 10
bb 10
Right
Error
cc 20
aa 10
bb 10
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
int n;
struct node{
	string name;
	int score;
	int id; 
}p1[305],p2[305];
bool cmp(node a,node b){
	if(a.score!=b.score) return a.score>b.score;
	else return a.id<b.id;
}
int main() {
	while(~scanf("%d",&n)){
		for(int i=0;i<n;i++){
			cin>>p1[i].name>>p1[i].score;
			p1[i].id=i;
		}
		sort(p1,p1+n,cmp);
		int flag1=0,flag2=0;
		for(int i=0;i<n;i++){
			cin>>p2[i].name>>p2[i].score;
			if(p2[i].name!=p1[i].name) flag1=1;
			if(p2[i].score!=p1[i].score) flag2=1;
		}
		if(!flag1&&!flag2) cout<<"Right\n";
		else if(flag1&&!flag2){
			cout<<"Not Stable\n";
			for(int i=0;i<n;i++) 
				cout<<p1[i].name<<' '<<p1[i].score<<endl;
		}
		else{
			cout<<"Error\n";
			for(int i=0;i<n;i++) 
				cout<<p1[i].name<<' '<<p1[i].score<<endl;
		}
	}
	return 0;
}

 

 

 HDU 无题(“都是套路”)

 

就要复试了,外地的考生都要在学校附近住宾馆了。假设在学校附近有C家宾馆,并且这些宾馆只有单人房,而每家宾馆的价格不一样,学生们都想找价格便宜的住,所以现在需要你的帮助,当有学生需要住宾馆的时候,告诉他哪个宾馆还有空的房间并且价格最便宜。而且有一个要求,同一个组的学生要住在同一个宾馆。

Input

输入包括多组数据。输入首先包括一个整数T(T <= 50),代表有T组数据。
每组数据首先是一个整数C(C <= 100),代表宾馆的个数,接下来是C行数据,每行3个整数,第一个代表宾馆的编号(<=1000),第二个是宾馆的房间数(<=50),第三个是宾馆的价格(<=1000)。
然后是一个整数T (T <= 1000),代表想找宾馆住的小组,接下来的T行每行代表一个要找宾馆的小组,每个小组不超过10人。

Output

对于每组数据中的想找宾馆的小组,输出他们应该找的宾馆编号。如果没有合适的宾馆或已经住满,输出”sorry”.

Sample Input

1
2
1 2 100
2 3 120
4
3 
1
1
5

Sample Output

2
1
1
sorry
#include<iostream>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
struct node {
	int id,room,cost;
} p[105];
bool cmp(node a,node b){
	if(a.cost!=b.cost) return a.cost<b.cost;
	else if(a.room!=b.room) return a.room>b.room;
	else return a.id<b.id; 
}
int main() {
	int t,c,n,num,idx;
	cin>>t;
	while(t--){
		cin>>c;
		for(int i=0; i<c; i++)
			cin>>p[i].id>>p[i].room>>p[i].cost;
		sort(p,p+c,cmp);
		cin>>n;
		for(int i=0;i<n;i++){
			cin>>num;
			int flag=0;
			for(int j=0;j<c;j++){
				if(p[j].room>=num){
					flag=1;
					idx=p[j].id;
					p[j].room-=num;
					break;
				}
			}
			if(!flag) cout<<"sorry\n";
			else cout<<idx<<endl;
 		}
	}
	return 0;
}

 

 

 CF833A-The Meaningless Game(数学思维+数据处理)

 

题目大意:给出nn场游戏的结果,每场有若干轮,每轮有一个数k,赢者乘k^2,输者乘k,问是否可能出现输入结果。
解题思路:数学思维,最终a*b肯定是一个三平方数,且要满足a和b能被三次方根整除。

注意:pow和sqrt返回的都是double型,如果强转一下,默认向下取整,所以这里需要四舍五入,用round函数。

 

#include<iostream>
#include<cmath>
#define ll long long
using namespace std;
int main() {
	int n,a,b,mul;
	cin>>n;
	while(n--) {
		scanf("%d%d",&a,&b);
		int tmp=(round)(pow(1.0*a*b,1.0/3));
		if(tmp*tmp*tmp==a*b&&a%tmp==0&&b%tmp==0) cout<<"Yes\n";
		else cout<<"No\n";
	}
	return 0;
}

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值