目录
喝汽水问题
变种水仙花
奇偶分离
判断有序序列
有序序列合并
X型图案
箭型图案
猜排名
猜凶手
1瓶汽水1元,2个空瓶可以换一瓶汽水,给20元,可以多少汽水(编程实现)。
设置三个变量,金钱,空瓶数和汽水数。其中初始汽水数和空瓶为金钱总数。利用空瓶回收进行循环,需要注意当空瓶为奇数时需要保留下来以便进行下一次兑换。
int money = 0;
int total = 0;
int empty = 0;
scanf("%d", &money);
total = money;
empty = money;
while (empty >= 2)
{
total += empty / 2;
empty = empty / 2 + empty % 2;
}
printf("%d\n", total);
我们可以通过多组输入发现金钱和汽水数有一个确定的规律: total = moeny*2 +1
对于乘号前面的数,可通过/10,/100...获取,乘号后面的数通过%10,%100...获取,结束条件是不超过当前位数。
#include
#include
int main() {
int i = 0;
for(i = 10000; i <= 99999; i++)
{
int sum = 0;
int j = 0;
for(j = 1;j<=4;j++)
{
int ret = (int)pow(10,j);
sum += (i%ret) * (i/ret);
}
if(sum == i)
printf("%d ",sum);
}
return 0;
}
提供一种时间复杂度最低的做法——双指针遍历。左边遇到偶数,右边遇到奇数双双交换,当left>=right时,没有必要再交换。
void move_even_odd(int arr[], int sz)
{
int left = 0;
int right = sz - 1;
while (left < right)
{
//从前往后找一个偶数停下来
while ((left < right) && (arr[left] % 2 == 1))
{
left++;
}
//从后往前找一个奇数停下来
while ((left < right) && (arr[right] % 2 == 0))//
{
right--;
}
if (left < right)
{
int tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
left++;
right--;
}
}
}
需要注意避免越界和全奇全偶的情况,在移动和交换前都要判断left是否小于right。
有序序列判断_牛客题霸_牛客网
设置两个开关变量,根据升序和降序分别处理,要单独拎出其中有相等的情况(1 1 2 2 4), 和全等的情况(1 1 1 1 1)。
#include
int main() {
int n = 0;
scanf("%d",&n);
int arr[n];
int i=0;
int flag1 = 0;//升序
int flag2 = 0;//降序
for(i=0;i< n;i++)
{
scanf("%d", &arr[i]);
}
for(i=0;i arr[i+1])
flag2 = 1;
//等于不做处理
}
if(flag1 + flag2 <=1)//包含数据全等的情况
printf("sorted\n");
else
printf("unsorted");
return 0;
}
方法一:两个数组合并成一个数组进行快排。
#include
#include
int compare(const void* a, const void* b)
{
return *(int*)a - *(int*)b;
}
int main()
{
int n, m;
scanf("%d %d", &n, &m);
int arr1[n] ;
int arr2[m] ;
int arr3[n+m];//初始化为0
int i = 0;
int j = 0;
for (i = 0; i < n; i++)//自己设置字符串数据
{
scanf("%d", &arr1[i]);//别忘了取地址
}
for (i = 0; i < m; i++)
{
scanf("%d", &arr2[i]);
}
for (i = 0; i < n+m; i++)
{
if (i < n)
arr3[i] = arr1[i];
else
{
arr3[i] = arr2[j];
j++;
}
}
qsort(arr3, n+m, sizeof(int), compare);
for (i = 0; i < n+m; i++)
{
printf("%d ", arr3[i]);
}
return 0;
}
方法二:利用指针比较大小遍历数组,再输出数组剩余部分。
#include
int main()
{
int n, m;
scanf("%d %d", &n, &m);
int arr1[n];
int arr2[m];
int i = 0;
int j = 0;
for (i = 0; i < n; i++)//自己设置字符串数据
{
scanf("%d", &arr1[i]);//别忘了取地址
}
for (i = 0; i < m; i++)
{
scanf("%d", &arr2[i]);
}
i = 0;
j = 0;
while(i
X形图案_牛客题霸_牛客网
规律是二维数组的主对角线和副对角线,主对角线行列相等,副对角线行列和为一个定值。
#include
int main()
{
int i = 0,n = 0;
while (scanf("%d", &n) == 1)
{
for (i = 0; i < n; i++)//打印出X图形其实就是模拟二维数组,规律是对角线输出
{
int j = 0;
for (j = 0; j < n; j++)
{
if (i == j || i+j == n-1)
printf("*");
else
printf(" ");//剩余的直接为 ‘ ’
}
printf("\n");
}
}
return 0;
}
箭形图案_牛客题霸_牛客网
要点:分上半和下半打印,注意空格可以两个一打印,灵活利用行(i)的变化打印。
#include
int main()
{
int i = 0,n = 0;
while (scanf("%d", &n) == 1)
{
for (i = 0; i < n+1; i++)
{
int j = 0;
for (j = 0; j < n-i; j++)
{
printf(" ");
}
for(j = 0;j<=i;j++)
{
printf("*");
}
printf("\n");
}
for (i = 0; i
5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果:
A选手说:B第二,我第三;
B选手说:我第二,E第四;
C选手说:我第一,D第二;
D选手说:C最后,我第三;
E选手说:我第四,A第一;
逻辑推断题,可以利用穷举法, 比赛结束后,每位选手都说对了一半,请编程确定比赛的名次。说对一半可以译为1+0 == 1,每位可以译为&&。
int a = 0;
int b = 0;
int c = 0;
int d = 0;
int e = 0;
for (a = 1; a <= 5; a++)
{
for (b = 1; b <= 5; b++)
{
for (c = 1; c <= 5; c++)
{
for (d = 1; d <= 5; d++)
{
for (e = 1; e <= 5; e++)
{
if (((b==2) + (a==3) == 1) &&
((b==2) + (e==4) == 1) &&
((c==1) + (d==2) == 1) &&
((c==5) + (d==3) == 1) &&
((e==4) + (a==1) == 1))
{
if((a * b * c * d * e == 120) &&(a+b+c+d+e==15))
printf("a=%d b=%d c=%d d=%d e=%d\n", a, b, c, d, e);
}
}
}
}
}
}
可以看到在输出结果时我添加了判断条件,是因为结果有多个名次重名了,因为遍历时并没有考虑名次占用问题,所以我们根据每个排名的独特性添加判断筛选出不重复的排名即可。
日本某地发生了一件谋杀案,警察通过排查确定杀人凶手必为4个嫌疑犯的一个。
以下为4个嫌疑犯的供词:
A说:不是我。
B说:是C。
C说:是D。
D说:C在胡说。
已知3个人说了真话,1个人说的是假话。
现在请根据这些信息,写一个程序来确定到底谁是凶手。
先假定一人说的是假话。3真话,1假话:4人逻辑判断之和为3。
int killer = 0;
for (killer = 'A'; killer <= 'D'; killer++)
{
if ((killer != 'A') + (killer == 'C') + (killer == 'D') + (killer != 'D') == 3)
printf("%c", killer);
}