acm第一次训练

找出单身狗

题目描述
实践课要进行分组,班里有n个人,每组有一个序号且每组人数为双数个,可是有一个单身狗一个人一组,请你找出单身狗的小组序列号。
输入格式
输入包含多组测试样例。每组样例第一行为一个正整数n(1<=n<=1000000,并且n为奇数),表示班级人数。
接下来的一行为n个正整数表示每人所在小组的序号,所有的数都小于2^31。
当n=0时,输入结束。
输出格式
输出只出现过一次的那个序号,每组结果占一行。
样例输入
5
1 1 3 2 2
3
1 2 1
0
样例输出
3
2
提示/说明
该题很容易超时,注意优化
分类
 //本题解析
 方法一:数组下标记录法,正常人的思路,但是数组开销大,不合适。
 方法二:set
 方法三:位运算,此题中用到的是异或 ^

 ios::sync_with_stdio(false);
 cin.tie(0); 
 //加快cin输入输出流,使其逼近与scanf
 //位运算对于从一群偶数中找出唯一的奇数非常有效;
//ac代码
 #include <iostream>
 using namespace std;
 
 int main(){
 	ios::sync_with_stdio(false);
 	cin.tie(0);
 	int n;
 	while(cin>>n&& n){
 		if(n==0) break;
 		int m,sum=0;
 		for(int i=0;i<n;i++){
 			cin>>m;
 			sum^=m;
		 }
		 cout<<sum<<endl;
	 }
	 
 } 

//对set进行了了解,并试做书本例题 hdu 2094
 #include <iostream>
 #include <set>
 using namespace std;

//set集合
//当使用二叉搜索树处理数据时候,使用map或者set将非常高效;
//例题:产生冠军
int main(){
	set<string> A,B;
	string a,b;
	int n;
	while(cin>>n&&n){
		int m;
		for(int i=0;i<n;i++){
			cin>>a>>b;
			A.insert(a);
			A.insert(b);
			B.insert(b);
		}
		if(A.size()-B.size()==1){
			cout<<"true"; 
		}
		else cout<<"false";
		A.clear();
		B.clear();
	} 
	return 0;
}
 
 
  
//尝试用set解决一个例题

“单身狗”是中文对于单身人士的一种爱称。本题请你从上万人的大型派对中找出落单的客人,以便给予特殊关爱。

输入格式:
输入第一行给出一个正整数 N(≤50000),是已知夫妻/伴侣的对数;随后 N 行,每行给出一对夫妻/伴侣——为方便起见,每人对应一个 ID 号,为 5 位数字(从 0000099999),ID 间以空格分隔;之后给出一个正整数 M(≤10000),为参加派对的总人数;随后一行给出这 M 位客人的 ID,以空格分隔。题目保证无人重婚或脚踩两条船。

输出格式:
首先第一行输出落单客人的总人数;随后第二行按 ID 递增顺序列出落单的客人。ID 间用 1 个空格分隔,行的首尾不得有多余空格。

输入样例:
3
11111 22222
33333 44444
55555 66666
7
55555 44444 10000 88888 22222 11111 23333
输出样例:
5
10000 23333 44444 55555 88888
//没有ac的代码,我自己写的。参照代码在后走一格;
#include <set>
#include <map>
#include <vector>
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
const int MAX=10001;
//题目中的落单有两种情况,但都可以一个判断方式:这个人的对象是否在一行人中; 
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	
	//st 和 t[]  数组同数据; 
	set<int> st;
	int t[MAX]; 
	//map做映射; 
	map<int, int > mp;
	//vec存储要输出的数据; 
	vector<int> dsg;
	int N;
	cin>>N;
	for(int i=0;i<N;i++){
		int a,b;
		cin>>a,b;
		mp[a]=b;
		mp[b]=a;
	}
	int M;
	cin>>M;
	for(int i=0;i<M;i++){
		
		cin>>t[i];
		st.insert(t[i]);
	}
	//开始
	int num=0;
	for(int i=0;i<M;i++){
		if(st.find(mp[t[i]])==st.end()){
			num+=1;
			dsg.push_back(t[i]);
		}
	} 
	cout<<num<<endl;
	sort(dsg.begin(),dsg.end());
	for(int i=0;i<dsg.size();i++){
		//cout<<"进入这个循环";
		cout<<dsg[i]<<" ";
	}
	return 0;
} 
//参照代码博客
https://blog.csdn.net/KLSZM/article/details/108630101

无处不在的宗教

在线裁判	问题集	作者	在线竞赛	用户
Web Board
主页
F.A.Qs
统计图表	
问题
提交问题
在线状态
Prob.ID:
注册
更新您的信息
作者 ranklist
当前比赛
过去的比赛
预定比赛
颁奖比赛	
用户身份:	
密码:	
注册  
语:
默认
无处不在的宗教
时限: 5000MS		内存限制: 65536K
提交总数: 52302		接受: 24159
描述

当今世界上有如此多的不同宗教,很难对它们进行追踪。您有兴趣了解您所在大学的学生信仰多少种不同的宗教。

您知道您所在的大学有 n 个学生 (0 < n <= 50000)。你问每个学生他们的宗教信仰是不可行的。此外,许多学生不愿意表达他们的信仰。避免这些问题的一种方法是询问 m (0 <= m <= n(n-1)/2) 对学生并询问他们是否信仰相同的宗教(例如,他们可能知道他们是否参加相同的宗教活动)教会)。从这些数据中,您可能不知道每个人的信仰是什么,但您可以了解校园中可能代表多少种不同宗教的上限。您可以假设每个学生最多信奉一种宗教。
输入

输入由许多情况组成。每个案例都以一行指定整数 n 和 m 开始。接下来的 m 行每行由两个整数 i 和 j 组成,指定学生 i 和 j 信仰相同的宗教。学生编号为 1 到 n。输入的结束由一行指定,其中 n = m = 0。
输出

对于每个测试案例,将案例编号(从 1 开始)打印在一行上,然后是该大学学生信仰的不同宗教的最大数量。
样本输入

10 9
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
1 10
10 4
2 3
4 5
4 8
5 8
0 0
样本输出

Case 1: 1
Case 2: 7
暗示

输入量大,推荐使用scanf。
来源

艾伯塔省大学生程序设计大赛 2003.10.18
[提交] [返回] [状态] [讨论]

首页   返回  顶部

版权所有 2003-2013 应福臣,徐鹏程,谢迪
任何问题,请联系管理员


这个题没在考试中出,我从boj上找到。
//并查集
//#include <bits/stdc++.h>
#include <iostream>
# include <cstdio>
using namespace std;
const int maxn = 55555;
int s[maxn + 1];
int n, m;
void init_set() {
	for (int i = 1; i <= maxn; i++) {
		s[i] = i;
	}
}
int find_set(int i) {
	if (i == s[i]) {
		return i;
	}
	else return find_set(s[i]);
	//return s[pos] == pos ? pos : (s[pos] = find_set(s[pos]));
}
void union_set(int x, int y) {
	x = find_set(x);
	y = find_set(y);
	if (x != y) {
		//n--;//可避免for的超时;
		s[y] = s[x];//此处x=s[x],所以两种写法都行; 
	}
}
int main() {


	int x, y;
	int time = 0;
	while (scanf("%d %d", &n, &m), m || n) {
		time++;

		init_set();
		for (int i = 1; i <= m; i++) {
			scanf("%d %d", &x, &y);
			union_set(x, y);

		}
		//查看有多少个集合;
		int ans = 0;
		for (int i = 1; i <= n; i++) {
			if (s[i] == i) {
				ans++;
			}
		}
		printf("Case %d: %d\n", time, ans);
	}
}

去重

题目描述
本题要求对n个无序的数进行去重,即n个数中会有些数字会重复出现,你要做的就是仅保留重复数中第1次出现的数,输出删除后的数列。
输入格式
第一行一个数N(N≤1000)
接下来N行,每行1个整数(int)
输出格式
输出去重后的数列,每个数一行。
样例输入
5
1
2
1
3
1
样例输出
1
2
3
分类
//考试时候思路是 记录出现的次数,若大于0则不输出;否则输出;
//联盟推荐让用set集合,但我寻思着出现顺序并不是当时输入的顺序,有疑惑;
//其实是,将将要打印的数据在set中查找一遍,若没有找到,则打印,并放入集合;

//ac代码
#include <iostream>
#include <set>
using namespace std;
const int MAX=1001;
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	
	int N;
	set<int > st;
	cin>>N;
	for(int i=0;i<N;i++){
		int m;
		cin>>m;
		if(st.find(m)==st.end()){//没有找到 
			st.insert(m);
			cout<<m<<endl; 
		}
	}
} 

I LOVE WANG


1006: I LOVE WANG
时间限制:1.000s 内存限制:128MB
   
题目描述
    
    时间渐渐过去,WANG成为了大家心目中的超级大佬。cy就是他的粉丝之一。于是cy决定要编一 个程序,将一段仅由英文字母构成的字符串变成只有WANG存在的"世界"。他的想法是将字符重新调整顺序,按WANGWANG....这样的顺序输出,并忽略其他字符。当然,四种字符(不区分大小写)的个数不一定一样多,若某种字符已经输出完,则余下的字符仍按照WANG的顺序打印,直到所有字符都被输出。

	

输入格式
输入在一行中给出一个长度不超过10000的非空字符串。

输出格式
在一行中按题目要求输出排序后的字符串。题目保证输出非空。

样例输入
acGcnlWnoRwNrGNhWnjkNhWFfuAesSKwg
样例输出
WANGWANGWNGWNWNN
分类

//想法
我考试时候思路是数组下表存储,将A~Z 按照char数值数组下标,内容为出现次数进行记录,但看了题解发现这样数组开销较大,其实只统计WANG 这四个字母的出现顺序即可;
这个题不准备写代码了;

串字符


1002: 串字符
时间限制:1.000s 内存限制:128MB
   
题目描述
某天上机课,czy大佬做完了上机作业,闲的没事,打算编程将一些字符串给串起来。结果她发现就这么串起来没有意思,于是她决定把这些字符串按一定顺序串起来构成一个字典序最小的字符串。你来帮他完成叭!
输入格式
第一行T,表示有T组数据(T<=100)。接下来T组数据每组第一行一个正整数N(N<=7000),表示有字符串个数。接下来N行,每行一个字符串(字符串只包含小写字母,长度不超过100)。
输出格式
T行,每行一个字符串。
样例输入
1
3
ab
a
abc
样例输出
aababc
分类
菜单
考试时候没做出来,因为对字典序陌生,对字符串的各种方法也不熟悉;
//ac代码
#include <iostream>
#include <algorithm>
using namespace std;
const int MAX=7001;
bool cmp (const string &a,const string &b){
	return a+b<b+a;
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	int N;
	cin>>N;
	while(N--){
		string array[MAX];
		int m;
		cin>>m;
		for(int i=0;i<m;i++){
			string str;
			cin>>str;
			array[i]=str;
		}
		sort(array,array+m,cmp);
		for(int i=0;i<m;i++){
			cout<<array[i];
		}
		cout<<endl;
	}
} 

一起画方块


1007: 跟zxm一起画方块
时间限制:1.000s 内存限制:128MB
   
题目描述


    联盟zxm作为组花呼吁大家一起学习编程,甚至以身作则编写代码。于是在1128日为庆祝第一次训练赛成功开启。zxm编写了一段代码:在屏幕上画一个正方形。现在你也跟着她画吧!

输入格式
输入在一行中给出正方形边长N(3≤N≤21)和组成正方形边的某种字符C,间隔一个空格。

输出格式
输出由给定字符C画出的正方形。但是注意到行间距比列间距大,所以为了让结果看上去更像正方形,我们输出的行数实际上是列数的50%(四舍五入取整)。
样例输入
11 *
样例输出
***********
***********
***********
***********
***********
***********
分类

并不一定要四舍五入取整作为行数,这道题判断50%,用判断奇偶数就可以;
void cal(int n){
	if(n%2==1){
		return n/2+1;
	}
	else return n/2;
}

寻找回文串


1004: 寻找回文串
时间限制:1.000s 内存限制:128MB
   
题目描述
回文串就是正序与倒序输出相同的字符串,即abcba,121等。本题要求你对给定字符串,输出其中最长的回文串的长度。例如,给定:are chy&&yhc error?,最长的回文串的长度就是re chy&&yhc er,于是你应该输出14。
输入格式
输入在一行中给出长度不超过1000的非空字符串。
输出格式
在一行中输出最长的回文串的长度。
样例输入
are chy&&yhc error?
样例输出
14
分类

//字符串相关题型,不敢做;
找回文串就从头到尾,两重循环找相同字母,对相夹的字符串进行是否为对称串的判断;
//ac代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX=1001;
int str_len;
bool judge(char *str,int start,int end){
	int j=end;
	for(int i=start;i<=end;i++){
		if(str[i]!=str[j]) return false;
		j--;
	}
	return true;
}
int cal_right(char *str,int start){
	for(int i=str_len-1;i>=start;i--){
		if(str[i]==str[start]){
			if(judge(str,start,i)){
				return i-start+1;
			}
		}
	}
	return 0;
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	int max=-1;
	//string str;
	char str[MAX];
	cin.getline(str,MAX);
	//str_len=str.length();
	str_len=strlen(str);
	for(int i=0;i<str_len;i++){
		int dis=cal_right(str,i);
		if(max<dis){
			max=dis;
		}
	}
	cout<<max;
}

铺设光缆


1000: 铺设光缆
时间限制:1.000s 内存限制:128MB
   
题目描述
    hh贫穷的老家终于迎来了铺设光缆的一天,政府要求在N个村庄之间铺设光缆,使得每两个村庄之间至少存在一条通路可以通信。但是铺设光缆费用极高,为了减少花销,让身为程序员的你帮助计算铺设完成光缆的最低花销。
输入格式
    输入第一行为一个整数T(1≤T≤50),表示有T组数据。
每行输入第一行是两个正整数N,E(2≤N≤500,N≤E≤N*(N-1)/2),分别表示村庄个数和原有光缆条数。
接下来E行,每行包含三个整数A,B,K(0≤A,B<N,0≤K<1000)。A和B分别表示光缆铺设的起始村庄代号。如果K=0,表示该道路已经铺设好了光缆。如果K为正整数,表示铺设光缆连接着两村庄需要花费K的代价。题目保证输入中无重边,也没有起始村庄相同的边。
输出格式
对于每组输入,输出铺设好光缆所需的最小代价,以保证每两个村庄之间至少存在一条通路可以通信。
样例输入
1
3 3
0 1 5
0 2 0
1 2 9
样例输出
5
提示/说明
最小生成树
分类

涉及到最小生成树算法;
//书本例题热身:
还是畅通工程
Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 84024    Accepted Submission(s): 38061


Problem Description
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
 

Input
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。
当N为0时,输入结束,该用例不被处理。
 

Output
对每个测试用例,在1行里输出最小的公路总长度。
 

Sample Input
3
1 2 1
1 3 2
2 3 4
4
1 2 1
1 3 4
1 4 1
2 3 3
2 4 2
3 4 5
0
 

Sample Output
3
5
Huge input, scanf is recommended.
 

Hint
Hint
 

Source
浙大计算机研究生复试上机考试-2006
//还是畅通工程ac
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX=103;
int s[MAX];
int m;//输入的边的数量; 
struct Edge{
	int u,v,w;
} edge[MAX*MAX];//这里MAX*MAX开多了,边的数量最多为n*(n-1)/2个,可能怕超出;


void init_s(){
	for(int i=0;i<MAX;i++){
		s[i]=i;
	}
} 
int find(int u){
	return s[u]==u?u:find(s[u]);
}
bool emp(Edge x,Edge y){
	return x.w<y.w;
}
int kruscal(){
	int ans=0;
	init_s();
	sort(edge,edge+m,emp);
	for(int i=0;i<m;i++){
		int b=find(edge[i].u);
		int c=find(edge[i].v);
		if(b==c) continue;
		s[c]=b;//合并
		ans+=edge[i].w; 
	}
	return ans;
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n;
	while(cin>>n&&n){
		int u,v,w;
		m=n*(n-1)/2;
		for(int i=0;i<m;i++){
			cin>>edge[i].u>>edge[i].v>>edge[i].w;
		}
		cout<<kruscal()<<endl;
	}
}


//题解ac
//几乎与书本习题答案一致;改动地方仅io和MAX上限;
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX=503;
int s[MAX];
int m;//输入的边的数量; 
struct Edge{
	int u,v,w;
} edge[MAX*MAX];//这里MAX*MAX开多了,边的数量最多为n*(n-1)/2个,可能怕超出;


void init_s(){
	for(int i=0;i<MAX;i++){
		s[i]=i;
	}
} 
int find(int u){
	return s[u]==u?u:find(s[u]);
}
bool emp(Edge x,Edge y){
	return x.w<y.w;
}
int kruscal(){
	int ans=0;
	init_s();
	sort(edge,edge+m,emp);
	for(int i=0;i<m;i++){
		int b=find(edge[i].u);
		int c=find(edge[i].v);
		if(b==c) continue;
		s[c]=b;//合并
		ans+=edge[i].w; 
	}
	return ans;
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n;
	cin>>n;
	while(n--){
		int u,v,w;
		int mm;
		cin>>mm>>m;
		for(int i=0;i<m;i++){
			cin>>edge[i].u>>edge[i].v>>edge[i].w;
		}
		cout<<kruscal()<<endl;
	}
}

//在练习了书本上题后,感觉这道题使用书本上源代码也能ac 

1008: 逃げる!电気石の洞穴


1008: 逃げる!电気石の洞穴
时间限制:1.000s 内存限制:128MB
   
题目描述
眼见着皮卡丘就要到来。。。然而这里是  xxx(被围在)  工地  xx(之中)  ,一不小心就掉进了施工的坑里,然后触动了暗藏在地下的时空开关,经过时空隧道掉进了合众地区吹寄市南边的电石洞穴中。。。
更加可怕的时,火箭队正在电石洞穴中进行秘密的任务,堵住了所有的洞口,然而山洞中遍布着一种神奇的道具--あなぬけのヒモ,只要获得这种道具,便可立马脱离洞穴~
现在把电石洞穴看作一个二维平面,'.'代表可以走的空地,'R'代表皮卡丘当前的位置,'#'代表这里是个障碍物,'F代表这里是逃脱的道具,'d'代表这里有个电电虫(这里应该有个图片,但是怕吓到人就不放了),它可以从上下左右四个格子吸取电力,皮卡丘只要走到或者一开始就在电电虫可以吸取的位置,就会筋疲力尽无法逃脱,此外‘D’代表这里有个电蜘蛛(电电虫的进化形态,照片也不放了= =其实电石洞穴中并没有电蜘蛛,但是万一哪只电电虫进化了呢),它可以从上下左右四个方向吸取电力,但是它不会越过障碍物吸取且它们都不会移动。除此之外,电石洞穴中还有隐藏的雷之石,以‘L’标记,其实它并不会对皮卡丘造成伤害,但是皮卡丘不想接近它,所以雷之石周围的八个格子也是不能走的。看了上面一段话,是不是觉得这道题特别麻烦?考虑到这道题目有那么一点点麻烦,所以本题并不会出现‘d’,‘D’,‘L’。已知皮卡丘只能往上下左右走,每走一步需要1秒,现在请你帮他找一条最快逃离洞穴的线路,输出这个时间,如果怎么都逃不出去,输出"Poor Pikachu. "。
输入格式
输入数据第一行为T,表示数据组数。(1<=T<=100)
每组第一行为两个数n,m,表示迷宫的大小。(1<=n,m<=200)
接下来n行,每行m个字符。题目保证只出现描述中所说的字符。
输出格式
对于每组数据,如果皮卡丘能安全逃离,输出最小时间。
否则输出"Poor Pikachu."
样例输入
1
3 4
#.R#
F#..
....
样例输出
5
分类

//书本上的题作为练习

问题描述
有一个长方形的房间,铺着方砖。每个瓷砖都是红色或黑色的。一个人站在一块黑色的瓷砖上。从一块瓷砖,他可以移动到四个相邻的瓷砖之一。但是他不能在红色瓷砖上移动,他只能在黑色瓷砖上移动。

编写一个程序来计算他通过重复上述动作可以达到的黑色瓷砖的数量。
 
输入
输入由多个数据集组成。一个数据集以一行包含两个正整数 W 和 H 开始;W 和 H 分别是 x 和 y 方向上的瓦片数量。W和H不超过20

,数据集中还有H行,每行包含W个字符。每个字符代表瓷砖的颜色如下。

'.' - 黑色瓷砖
'#' - 红色瓷砖
'@' - 黑色瓷砖上的男人(在数据集中只出现一次)
 

输出
对于每个数据集,您的程序应该输出一行,其中包含他可以从初始图块(包括其自身)到达的图块数量。
 

样本输入
6 9
....#.
.....#
......
......
......
......
......
#@...#
.#..#。
11 9
.#........
.#.#######。
.#.#.....#.
.#.#.###.#。
.#.#..@#.#。
.#.######.#。
.#.......#.
.#########。
…………
11 6
..#..#..#..
..#..#..#..
..#..#..###
..#..#..#@。
..#..#..#..
..#..#..#..
7 7
..#.#..
..#.#..
###.###
...@...
###.###
..#.#..
..#.#..
0 0
 

样本输出
45
59
6
13
 

来源
亚洲 2004,爱媛(日本),日本国内

//ac代码
# include <iostream>
# include <queue>
using namespace std;
const int MAX=23;
char room[MAX][MAX];
int dir[4][2]={
	{0,1},
	{1,0},
	{0,-1},
	{-1,0}
};
int X,Y,num;
# define check_fun(x,y) (x<X&&x>=0&&y<Y&&y>=0)

struct node{
	int x;
	int y;
};
void BFS(int begin_x,int begin_y){
	num+=1;//将起点计数;
	queue<node> q; 
	node start,next;
	start.x=begin_x;
	start.y=begin_y;
	q.push(start);
	while(!q.empty()){
		start=q.front();
		q.pop();
		for(int i=0;i<4;i++){
			next.x=start.x+dir[i][0];
			next.y=start.y+dir[i][1];
			if(check_fun(next.x,next.y)&&room[next.x][next.y]=='.') {
				room[next.x][next.y]='#';
				num+=1;
				q.push(next);
			}
		}
	}
}

int main(){
	int begin_x,begin_y;//起始位置; 
	while(cin>>Y>>X){
		if(X==0&&Y==0){
			break;
		}
		for(int i=0;i<X;i++){
			for(int j=0;j<Y;j++){
				cin>>room[i][j];
				if(room[i][j]=='@') {
					begin_x=i;
					begin_y=j;
				}
			}
		}
		num=0;
		BFS(begin_x,begin_y);
		cout<<num<<endl; 
	}
	return 0;
}
//2021年12月4日10:52:15
//没有ac,报时间超限的错误,但是多个测试的输出结果是对的;
# include <iostream>
# include <queue>
using namespace std;
const int MAX=205; 
const int FALSE=-1;
char room[MAX][MAX];
bool vis[MAX][MAX]={false};
int dir[4][2]={
	{0,1},
	{1,0},
	{0,-1},
	{-1,0}
};
int X,Y;
bool check_fun(int x,int y) {
	if(x<X&&x>=0&&y<Y&&y>=0) return 1;
	else return 0;
}

struct Node{
	int x;
	int y;
	int stp;
	Node (int _x,int _y,int _stp){
		x=_x;
		y=_y;
		stp=_stp;
	}
};
int BFS(int begin_x,int begin_y){
	//num+=1;//将起点计数;
	queue<Node> q; 
	q.push({begin_x,begin_y,0});
	vis[begin_x][begin_y]=true;
	
	while(!q.empty()){
		Node start=q.front();
		q.pop();
		if(room[start.x][start.y]=='F') {
			return start.stp;
		}
		for(int i=0;i<4;i++){
			int nxt_x,nxt_y;
			nxt_x=start.x+dir[i][0];
			nxt_y=start.y+dir[i][1];
			
			if(check_fun(nxt_x,nxt_y)) {
				if(room[nxt_x][nxt_y]!='#'&&!vis[nxt_x][nxt_y]){
				//room[nxt_x][nxt_y]='#';
				vis[nxt_x][nxt_y]=true;
				q.push({nxt_x,nxt_y,start.stp+1});
				//cout<<"x轴坐标:"<<nxt_x<<" ""y轴坐标:"<<nxt_y <<endl; 
				
				}
			}
		}
	} 
	return FALSE;
}

int main(){
	int begin_x,begin_y;//起始位置; 
	int time;
	cin>>time; 
	while(time--){ //Y是行数,X是列数; 
		cin>>X>>Y;
		for(int i=0;i<X;i++){
			for(int j=0;j<Y;j++){
				cin>>room[i][j];
				
				if(room[i][j]=='R') {
					begin_x=i;
					begin_y=j;
				}
			}
		}
		//int num=0; 
		int NUM = BFS(begin_x,begin_y);
		if(NUM>=0) cout<<NUM<<endl; 
		else cout<<"Poor Pikachu."<<endl; 
	}
	return 0;
}

B.全市统考分配座位


1003: 全市统考座位分配
时间限制:1.000s 内存限制:128MB
   
题目描述
每年全市统考有不同学校的同学参加,要保证同一所学校的所有队员不能相邻,分配座位就很困难了。为此,教育部大佬www制定了如下策略:假设某考场有N所学校参赛,第i所学校分成了M[i]个小组,每组10位考生。令每校考生排成一列纵队,第i+1组的考生排在第i组后面。从第1所学校开始,各校的第1位考生顺次就坐,然后是各校的第2位考生......以此类推。如果最后只剩下1所学校的队伍还没有分配座位,则需要安排他们的队员隔位就坐。www大佬要求你用程序自动为各校生成考生的座位号,从1开始编号。
输入格式
输入在一行中给出参考的高校数N(不超过100的正整数);第二行给出N个不超过10的正整数,其中第i个数对应的第i所高校的小组数,数字间用空格分隔。
输出格式
从第i所高校的第1个小组开始,顺次输出考生的座位号。每组占一行,座位号间以1个空格分隔,行首尾不得有多余的空格。另外,每所高校的第一行按"#X"输出该校的编号X,从1开始。
样例输入
4
3 2 2 1
样例输出
#1
1 5 9 13 17 21 25 29 33 37
41 44 47 50 53 56 59 62 65 68
71 73 75 77 79 81 83 85 87 89
#2
2 6 10 14 18 22 26 30 34 38
42 45 48 51 54 57 60 63 66 69
#3
3 7 11 15 19 23 27 31 35 39
43 46 49 52 55 58 61 64 67 70
#4
4 8 12 16 20 24 28 32 36 40
分类

//ac代码
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
//用到了stl库; 
void handle(int N);
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	
	int N;
	while(cin>>N&&N){
		handle(N);
	}
} 
void handle(int N){
	vector<int> groupNum(N);//后面对数组内的数据进行输入,而不是push_back,故给空间;
	vector<vector<int> >list;//仅限于定义list是个二维的? 
	int sum=0;
	for(int i=0;i<N;i++){
		cin>>groupNum[i];
		sum+=groupNum[i]*10;
		list.push_back(vector<int>());
	} 
	int nxt=0;
	int last=-1;
	int now=1;
	while(sum>0){
		if(list[nxt].size()<groupNum[nxt]*10){
			if(last==nxt) now+=1;
			
			last=nxt;
			
			list[nxt].push_back(now);
			now+=1;
			sum-=1; 
		}
		nxt+=1;
		nxt%=N;
		
	} 
	for(int i=0;i<N;i++){
		cout<<"#"<<i+1<<endl;
		int cnt=0;
		for(auto j:list[i]){
			cout<<j;
			cnt+=1;
			if(cnt%10==0) cout<<endl;
			else cout<<" ";
			
		}
	}
}
//ac13%,按照自己思路写的,不知道哪里错了;
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
//分座位用到了二维vector,故重做;
const int MAX=1001;
void handle(int N);
int main(){
	//因为需要每个组放一次,动态的, 所以使用vector动态添加最合适;
	ios::sync_with_stdio(false);
	cin.tie(0);
	
	int N;
	while(cin>>N&&N){
		handle(N);
	}
	
} 
void handle(int N){
	vector<int> groupNum;
	vector< vector<int> > vec;
	int sum=0;
	for(int i=0;i<N;i++){
		int num;
		cin>>num;
		groupNum.push_back(num);
		sum+=num*10;
		vec.push_back(vector<int>());
	}
	int s=1;
	int same_sign=-1;
	while(s<=sum){
		for(int i=0;i<N;i++){
			if(vec[i].size()>=10*groupNum[i]) break;
			if(same_sign==i) {
				sum+=1;
				s+=1; 
				//cout<<"这是将要添加的数:"<<s;
			}
			else same_sign=i;
			vec[i].push_back(s);
			s+=1;
		}
		
	}
	for(int i=0;i<N;i++){
		cout<<"#"<<i+1<<'\n';
		for(int j=0;j<10*groupNum[i];j++){
			cout<<vec[i][j];
			if((j+1)%10==0) cout<<'\n';
			else cout<<" ";	
		}
	}
}

因为对stl库不太熟悉,尤其是以上代码的push_back vector() 的时机不明确;要重新进行stl库的学习并请教;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值