CCF-CSP 2014-09(前四题)

第一题:

相邻数对


问题描述

给定n个不同的整数,问这些数中有多少对整数,它们的值正好相差1。

输入格式

  输入的第一行包含一个整数n,表示给定整数的个数。
  第二行包含所给定的n个整数。

输出格式

  输出一个整数,表示值正好相差1的数对的个数。

样例输入

6
10 2 6 3 7 8

样例输出

3

样例说明

  值正好相差1的数对包括(2, 3), (6, 7), (7, 8)。

评测用例规模与约定

  1<=n<=1000,给定的整数为不超过10000的非负整数。


解决方案:

先排个序,然后每一个与前一个相邻的相减,判断是否等于1

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
	int n;
	cin>>n;
	int a[1000];
	for(int i=0;i<n;i++){
		cin>>a[i];
	}
	sort(a,a+n);
	int res=0;
	for(int i=1;i<n;i++){
		if((a[i]-a[i-1])==1){
			res++;
		}
	
	}
	cout<<res<<endl;
	return 0;
}

 第二题:

画图


问题描述

在一个定义了直角坐标系的纸上,画一个(x1,y1)到(x2,y2)的矩形指将横坐标范围从x1到x2,纵坐标范围从y1到y2之间的区域涂上颜色。
  下图给出了一个画了两个矩形的例子。第一个矩形是(1,1) 到(4, 4),用绿色和紫色表示。第二个矩形是(2, 3)到(6, 5),用蓝色和紫色表示。图中,一共有15个单位的面积被涂上颜色,其中紫色部分被涂了两次,但在计算面积时只计算一次。在实际的涂色过程中,所有的矩形都涂成统一的颜色,图中显示不同颜色仅为说明方便。


  给出所有要画的矩形,请问总共有多少个单位的面积被涂上颜色。

输入格式

  输入的第一行包含一个整数n,表示要画的矩形的个数。
  接下来n行,每行4个非负整数,分别表示要画的矩形的左下角的横坐标与纵坐标,以及右上角的横坐标与纵坐标。

输出格式

  输出一个整数,表示有多少个单位的面积被涂上颜色。

样例输入

2
1 1 4 4
2 3 6 5

样例输出

15

评测用例规模与约定

  1<=n<=100,0<=横坐标、纵坐标<=100。


解决方案:

开一个布尔数组存放所有的格子,每次输入一个矩形,就将该矩形所包含的格式置位true,最后统计有多少个格子为true

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
	bool xy[110][110]={0};
	int n;
	cin>>n;
	for(int k=0;k<n;k++){
		int x1,y1,x2,y2;
		cin>>x1>>y1>>x2>>y2;
		for(int i=x1;i<x2;i++){
			for(int j=y1;j<y2;j++){
				xy[i][j]=1;
			}
		}
	}
	int res=0;
	for(int i=0;i<110;i++){
		for(int j=0;j<110;j++){
			if(xy[i][j]==true){
				res++;
			}
		}
	}
	cout<<res<<endl;
 } 

 第三题:

字符串匹配


问题描述

给出一个字符串和多行文字,在这些文字中找到字符串出现的那些行。你的程序还需支持大小写敏感选项:当选项打开时,表示同一个字母的大写和小写看作不同的字符;当选项关闭时,表示同一个字母的大写和小写看作相同的字符。

输入格式

  输入的第一行包含一个字符串S,由大小写英文字母组成。
  第二行包含一个数字,表示大小写敏感的选项,当数字为0时表示大小写不敏感,当数字为1时表示大小写敏感。
  第三行包含一个整数n,表示给出的文字的行数。
  接下来n行,每行包含一个字符串,字符串由大小写英文字母组成,不含空格和其他字符。

输出格式

  输出多行,每行包含一个字符串,按出现的顺序依次给出那些包含了字符串S的行。

样例输入

Hello
1
5
HelloWorld
HiHiHelloHiHi
GrepIsAGreatTool
HELLO
HELLOisNOTHello

样例输出

HelloWorld
HiHiHelloHiHi
HELLOisNOTHello

样例说明

  在上面的样例中,第四个字符串虽然也是Hello,但是大小写不正确。如果将输入的第二行改为0,则第四个字符串应该输出。

评测用例规模与约定

  1<=n<=100,每个字符串的长度不超过100。


解决方案:

若为1,则直接判断;若为0,则先全部转换成小写再判断。

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
	string str;
	cin>>str;
	int choice,n;
	cin>>choice;
	cin>>n;
	
	for(int i=0;i<n;i++){
		string s;
		cin>>s;
		if(choice==1&&(s.find(str))!=-1){
			cout<<s<<endl;
		}
		else if(choice==0){
			string temp;
			for(int j=0;j<s.size();j++){
				temp+=tolower(s[j]);
			}
			string tt;
			for(int k=0;k<str.size();k++){
				tt+=tolower(str[k]);
			}
		//	cout<<temp<<endl;
		//	cout<<tt<<endl;
			if(temp.find(tt)!=-1){
				cout<<s<<endl;
			}
		}
	}
	
}

 第四题:

最优配餐


问题描述

栋栋最近开了一家餐饮连锁店,提供外卖服务。随着连锁店越来越多,怎么合理的给客户送餐成为了一个急需解决的问题。
  栋栋的连锁店所在的区域可以看成是一个n×n的方格图(如下图所示),方格的格点上的位置上可能包含栋栋的分店(绿色标注)或者客户(蓝色标注),有一些格点是不能经过的(红色标注)。
  方格图中的线表示可以行走的道路,相邻两个格点的距离为1。栋栋要送餐必须走可以行走的道路,而且不能经过红色标注的点。


  送餐的主要成本体现在路上所花的时间,每一份餐每走一个单位的距离需要花费1块钱。每个客户的需求都可以由栋栋的任意分店配送,每个分店没有配送总量的限制。
  现在你得到了栋栋的客户的需求,请问在最优的送餐方式下,送这些餐需要花费多大的成本。

输入格式

  输入的第一行包含四个整数n, m, k, d,分别表示方格图的大小、栋栋的分店数量、客户的数量,以及不能经过的点的数量。
  接下来m行,每行两个整数xi, yi,表示栋栋的一个分店在方格图中的横坐标和纵坐标。
  接下来k行,每行三个整数xi, yi, ci,分别表示每个客户在方格图中的横坐标、纵坐标和订餐的量。(注意,可能有多个客户在方格图中的同一个位置)
  接下来d行,每行两个整数,分别表示每个不能经过的点的横坐标和纵坐标。

输出格式

  输出一个整数,表示最优送餐方式下所需要花费的成本。

样例输入

10 2 3 3
1 1
8 8
1 5 1
2 3 3
6 7 2
1 2
2 2
6 8

样例输出

29

评测用例规模与约定

  前30%的评测用例满足:1<=n <=20。
  前60%的评测用例满足:1<=n<=100。
  所有评测用例都满足:1<=n<=1000,1<=m, k, d<=n^2。可能有多个客户在同一个格点上。每个客户的订餐量不超过1000,每个客户所需要的餐都能被送到。


解决方案:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;


const int N=1010;
typedef pair<int, int>PII;
int dis[N][N];
bool no[N][N];
queue<PII> q;
	int n,m,k,d;

struct CUSTOMER{
	int x,y,w;
}cus[N*N];//可能有多个客户再同一个点上 
void bfs()
{
	int dx[]={-1,0,1,0},dy[]={0,1,0,-1};
	while(q.size()){
		auto t=q.front();
		q.pop();
		
		for(int i=0;i<4;i++){
			int x=t.first+dx[i];
			int y=t.second+dy[i];
			if(x<1||x>n||y<1||y>n||no[x][y]){
				continue;
			}
			if(dis[x][y]>dis[t.first][t.second]+1){
				dis[x][y]=dis[t.first][t.second]+1;
				q.push({x,y});
			}
		}
	}
}
int main()
{
	scanf("%d%d%d%d",&n,&m,&k,&d);
	memset(dis,0x3f,sizeof dis);//所有距离最初设为无穷大 
	for(int i=0;i<m;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		dis[x][y]=0;
		q.push({x,y}); 
	}
	for(int i=0;i<k;i++){
		scanf("%d%d%d",&cus[i].x,&cus[i].y,&cus[i].w);
	}
	for(int i=0;i<d;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		no[x][y]=true;
	}
	bfs();
	
	long long res=0;
	for(int i=0;i<k;i++){
		res+=dis[cus[i].x][cus[i].y]*cus[i].w;
	}
	printf("%lld",res);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值