题目描述
在一个旧式的火车站旁边有一座桥,其桥面可以绕河中心的桥墩水平旋转。一个车站的职工发现桥的长度最多能容纳两节车厢,如果将桥旋转 180180 度,则可以把相邻两节车厢的位置交换,用这种方法可以重新排列车厢的顺序。于是他就负责用这座桥将进站的车厢按车厢号从小到大排列。他退休后,火车站决定将这一工作自动化,其中一项重要的工作是编一个程序,输入初始的车厢顺序,计算最少用多少步就能将车厢排序。
输入格式
共两行。
第一行是车厢总数 N(≤10000)。
第二行是 N个不同的数表示初始的车厢顺序。
输出格式
一个整数,最少的旋转次数。
输入输出样例
输入
4 4 3 2 1
输出
6
思路
这道题可以用冒泡排序的方式来做,但是该题目并不求最终输出的序列,只是求一共有多少次,那我们可以求在一个数
前面有多少个比它小的数。有多少个就要换多少次。
代码
#include<stdio.h>
int main()
{
int n;
scanf("%d",&n);
int a[n],i,j,sum=0;
for(i=0;i<n;i++)
scanf("%d",&a[i]);
for(i=0;i<n;i++)
{
for(j=0;j<i;j++)
{
if(a[j]>a[i])
sum++;
}
}
printf("%d",sum);
return 0;
}
P1146 硬币翻转
题目描述
在桌面上有一排硬币,共NN枚,每一枚硬币均为正面朝上。现在要把所有的硬币翻转成反面朝上,规则是每次可翻转任意N-1N−1枚硬币(正面向上的被翻转为反面向上,反之亦然)。求一个最短的操作序列(将每次翻转N-1枚硬币成为一次操作)。
输入格式
一个自然数NN(NN为不大于100100的偶数)。
输出格式
第一行包含一个整数SS,表示最少需要的操作次数。接下来的SS行每行分别表示每次操作后桌上硬币的状态(一行包含NN个整数(00或11),表示每个硬币的状态:00――正面向上,和11――反面向上,不允许出现多余空格)。
对于有多种操作方案的情况,则只需操作的字典序最小输出一种。
注:操作的字典序:对于一次操作,1表示翻转,0表示不反转。
但是需要你输出的是每一次操作完的状态,0表示正面朝上,1表示反面朝上。
输入输出样例
输入
4
输出
4 0111 1100 0001 1111
思路
每一次翻转n-1枚硬币,那我们可以逆向思考,每一次就是翻转一枚硬币,通过数学规律我们可以发现,第i次时第i枚硬币不翻转。根据这个思路可以很简单的做出来。
#include<stdio.h>
int main()
{
int n;
scanf("%d",&n);
int a[n];
int i;
for(i=0;i<n;i++)
{
a[i]=0;
}
int j;
printf("%d\n",n);
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(i!=j)
{
if(a[j]==1) a[j]=0;
else a[j]=1;
}
printf("%d",a[j]);
}
printf("\n");
}
return 0;
}
P1150 Peter 的烟
题目描述
Peter 有 nn 根烟,他每吸完一根烟就把烟蒂保存起来,kk(k>1k>1)个烟蒂可以换一个新的烟,那么 Peter 最终能吸到多少根烟呢?
输入格式
每组测试数据一行包括两个整数 n, kn,k(1 < n, k≤10^8)。
输出格式
对于每组测试数据,输出一行包括一个整数表示最终烟的根数。
输入输出样例
输入1
4 3
输出 1
5
输入2
10 3
输出 2
14
说明/提示
对于 100% 的数据,1<n, k≤10^8。
思路
1、可以根据数学方法,直接算出最后的结果。
sum=n+(n-1)/(k-1)
2、我们可以用一个while模拟整个过程
首先我们用m来表示烟头的数量,当烟头的数量大于等于k时,进入循环,可以换取烟头。此时sum要加一,m烟头数量要减去k,换完烟后要加上换得到的那根烟头。直到烟头不足以换取烟为止。
代码
//#include<stdio.h>
//int main()
//{
// int n,k;
// scanf("%d %d",&n,&k);
// int sum=n+(n-1)/(k-1);
// printf("%d",sum);
// return 0;
//}
#include<stdio.h>
int main()
{
int n,k;
scanf("%d %d",&n,&k);
int sum=n;
int m=sum;//m为烟头的数量
while(m>=k)
{
m=m-k;
sum++;
m++;
}
printf("%d",sum);
return 0;
}