题目编号 | 标题 |
---|---|
0 | 晾衣绳 |
1 | 罗密欧与朱丽叶的约会 |
2 | 粉刷栅栏 |
3 | 马蹄印 |
T1
题目描述
奶牛们用N(1<=N<=1000)根绳子架起了晾衣绳,以便晒它们刚洗完的衣服。用它们不能弯曲的拇指,奶牛们彻底搞砸了这项工作。试想一下四根绳子是这样排列的:
绳子交叉了!这个,当然是无法接受的。
奶牛们想把晾衣绳整理好。它们迟钝的头脑只能处理"交换两根绳"的问题。然而奶牛们的手臂(牛的……也叫手臂)很短,受此限制,它们只能交换相邻两根绳子的端点(在上面或者是下边的固定器上)。以上面的图为例,需要做四次这样的交换才能使绳子变成想下面这样:
帮助奶牛们整理晾衣绳吧。请你找出最小的交换次数,使得这些晾衣绳能够排列整齐。
你将得到有关晾衣绳位置的描述,用整数来表示当前晾衣绳的顺序。这些晾衣绳被标上了1..N的数字。现在可以告诉你的是,这些晾衣绳在上面和下面各N个连接插槽上的出现顺序。
输入
第1行:一个整数N
第2..N+1行:
每一行有两个隔开的整数(均在1..N范围内)。第一个整数表示在上插槽上连接的绳子的ID,第二个整数表示在下插槽上连接的绳子的ID。第二行的两个整数就分别表示了1号上插槽和1号下插槽上连接的绳子;第三行则分别描述了2号上插槽和下插槽上连接的绳子……以此类推。
输出
第1行:一个整数,指出可以把晾衣绳全都弄直的最小交换次数
样例输入
4
4 1
2 3
1 4
3 2
样例输出
4
数据范围限制
1<=N<=1000
提示
样例说明
把3号绳上面的端点和它左边的交换,再和左边的交换一次。4号绳也做同样的工作。
这是道水题!!!
我给别人讲懂了,别人100,我10
过去的就让它过去吧,接下来进入正题:
冒泡排序、
#include<iostream>
#include<cstdio>
using namespace std;
int m,n,k,x,y,a[100100],b[100100];
int main(){
freopen("laundry.in","r",stdin);
freopen("laundry.out","w",stdout);
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i]>>b[i];
}
for(int i=1;i<n;i++){
if(b[i]!=a[i]){
for(int j=i+1;j<=n;j++){
if(b[j]==a[i]){
m=j;
break;
}
}
for(int j=m;j>i;j--){
int sw=b[j];
b[j]=b[j-1];
b[j-1]=sw;
k++;
}
}
}
cout<<k;
return 0;
}
T2
题目描述
农场主约翰养了两群有世仇的牛,它们被称为蒙塔戈斯家族和卡普鲁
特家族。蒙塔戈斯家族的成员,罗密欧,爱上了美丽的朱丽叶,但后者正好是卡普鲁特家族的成员。罗密欧希望与朱丽叶约会,但不希望卡普鲁特家族的其他成员发现(否则会有可怕的事情发生!)
罗密欧和朱丽叶希望在牧场栅栏边一块尽可能大的区域中相见,这样他们可以边散步边聊天。然而,这块区域中不应该有太多的卡普鲁特家族成员,否则,他们俩被发现的机会就会大得多。罗密欧发现在整个牧场栅栏边有P块草坪呈直线排列(1<=P<=1000),在这些草坪上总共有N位卡普鲁特家族的成员在吃草(1<=N<=1000)。每个卡普鲁特家族的成员在一些相邻的草坪上吃草。现在,罗密欧求助于聪明的你,希望你能找出一个最大的范围(指一些相邻的草坪),在这个范围的草坪中,至多有C(1<=C<=1000〉位卡普鲁特家族的成员在吃草。
输入
第一行,包含三个整数:N,P,C
第二至N+1行:每行包括一个整数X(1<=X<=P-1),代表一个卡普鲁特家族成员在栅栏边的第X和X+1块草坪之间吃草,多个卡普鲁特家族成员可以在同一块草坪内一起吃草。
输出
只有一行:一个整数,代表一个最大的草坪范围(指这些草坪的块数),在这个范围内最多只有C个卡普鲁特家族的成员在吃草。
样例输入
2 6 1
2
3
(解释:栅栏边的草坪分为六块:1 2 3 4 5和6。有两个卡普鲁特家族成员,一个在第二和第三块草坪上吃草,一个在第三和第四块草坪上吃草)
样例输出
3
(解释:在第四块至至第六块草坪间只有一个卡普鲁特家族的成员在吃草)
数据范围限制
1<=P<=1000
1<=N<=1000
1<=C<=1000
哇!前缀和耶!水题耶!
交上去一看,40分
赛后才发现x和x+1只算1头牛……
我们就用两个三个数组:a(牛的分布),b(牛的分布(几头)),f(牛的前缀和)就搞定了
#include<iostream>
#include<cstdio>
using namespace std;
long long m,n,k,x,y,f[100010],a[1001000],b[100100];
int main(){
freopen("meet.in","r",stdin);
freopen("meet.out","w",stdout);
cin>>n>>m>>k;
for(int i=1;i<=n;i++){
cin>>x;
b[x]++;
a[x]++;
a[x+1]++;
}
for(int i=1;i<=m;i++){
f[i]=f[i-1]+(a[i]-b[i]);
}
for(int i=1;i<=m;i++){
for(int j=i;j<=m;j++){
if(f[j]-f[i]<=k){
if(j-i>y)y=j-i;
}
}
}
cout<<y;
return 0;
}
T3
题目描述
题目:
农夫约翰最近正在将他的栅栏粉刷一下(这里所有的栅栏都是在一条直线上的)。他是这样来粉刷的:他从位置0出发,然后执行N条指令,例如,指令可以是“10 L”,表示约翰从当前的位置向左移动10个单位的距离,并且粉刷移动过程中遇到的栅栏,又或者是“15 R”,表示约翰从当前的位置向右移动15个单位的距离,并且粉刷移动过程中遇到的栅栏。
问题描述:
给定所有约翰需要移动的指令,请计算所有栅栏中至少被粉刷两次的栅栏的总长度。约翰最多远离初始位置1000000000个单位的距离。
输入
第一行一个正整数N。
接下来第2行到第N+1行,每行表示每条指令。
输出
只有一行一个整数,表示所有栅栏中至少被粉刷两次的栅栏的总长度。
样例输入
6
2 R
6 L
1 R
8 L
1 R
2 R
样例输出
6
数据范围限制
数据范围:1<=N<=100000。
提示
说明:样例中,有6个单位的长度至少被粉刷两次。分别是[-11,-8],[-4,-3],[0,2]。
全模拟,代码自己看
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
long long head,tail,k;
struct noo{
long long x,y;
}a[110010];
bool cmp(const noo&k,const noo&l){
return ((k.x<l.x)||(k.x==l.x)&&(k.y<l.y));
}
int main(){
freopen("paint.in","r",stdin);
freopen("paint.out","w",stdout);
int n;
cin>>n;
long long y=0;
for(int i=1;i<=n;i++){
char c;
long long x;
cin>>x>>c;
if(c=='R')x=y-x;
else x=y+x;
a[i].x=min(x,y);
a[i].y=max(x,y);
y=x;
}
sort(a+1,a+1+n,cmp);
head=a[1].x;tail=a[1].y;
for(int i=2;i<=n;i++){
if(a[i].y<head)continue;
if(a[i].y<=tail){
k=k+a[i].y-max(a[i].x,head);
head=a[i].y;
}
else if(a[i].x>tail){
head=a[i].x;
tail=a[i].y;
}
else if(a[i].x<head){
k=k+tail-head;
head=tail;
tail=a[i].y;
}
else{
k=k+tail-a[i].x;
head=tail;
tail=a[i].y;
}
}
cout<<k;
return 0;
}
T4
题目描述
题目:
虽然当奶牛贝里斯找到平衡序列后很高兴了,但是他现在对序列提出了一个更高的要求,就是要求每个序列中必须是先一定数量的左括号然后是与左括号相同数量的右括号。例如:(((()))),就是一个完美的平衡序列。
当贝里斯某天在农场上走的时候,他在地上发现了马蹄印,这个农场是一个N*N的方格,每个小方格中都有一个马蹄印。贝里斯希望从方格的最左上角的地方开始出发,然后每次可以向上或者向下或者向左或者向右移动一步,使得他走过的每个小方格中的马蹄印能够组成一个完美的平衡序列。当然了,贝里斯不能重复经过任何小方格。
问题描述:
请帮助贝里斯在这个N*N的方格中找出长度最长的完美序列的长度。
输入
第一行一个正整数N,表示农场的大小。
接下来N行,每行N个字符,表示N*N的方格上马蹄印的分布情况。
输出
只有一行一个整数,表示最长的完美序列的长度,如果不存在这样的完美序列(例如起始位置就是右括号),则输出0。
样例输入
4
(())
()((
(()(
))))
样例输出
8
数据范围限制
数据范围:2<=N<=5。
提前声明:((()()) )不符合要求
这就是一道纯dfs(剪枝都不用打)
#include<iostream>
#include<cstdio>
using namespace std;
int m,n,x,y;
char a[10][10];
bool f[10][10];
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
void dfs(int x,int y,int l,int r,int sum,int flag){
if(l==r){
if(sum>m)m=sum;
return;
}
if(r>l)return;
for(int i=0;i<4;i++){
int xx=x+dx[i],yy=y+dy[i];
if(xx<1||xx>n||yy<1||yy>n||f[xx][yy]==1)continue;
if(a[x][y]!=a[xx][yy]&&flag==1)continue;
if(a[x][y]!=a[xx][yy]&&flag==0){
f[xx][yy]=1;
dfs(xx,yy,l,r+1,sum+1,1);
f[xx][yy]=0;
}
if(a[x][y]==a[xx][yy]){
if(a[xx][yy]=='('){
f[xx][yy]=1;
dfs(xx,yy,l+1,r,sum+1,flag);
f[xx][yy]=0;
}
if(a[xx][yy]==')'){
f[xx][yy]=1;
dfs(xx,yy,l,r+1,sum+1,1);
f[xx][yy]=0;
}
}
}
}
int main(){
freopen("hshoe.in","r",stdin);
freopen("hshoe.out","w",stdout);
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j];
}
}
if(a[1][1]==')'){
cout<<0;
return 0;
}
f[1][1]=1;
dfs(1,1,1,0,1,0);
cout<<m;
return 0;
}