近期做简单题的时候,发现有的题不止一种解法,并且有的解法很简便,所以写一篇文章记录一下。
大家在看题目的时候也可以试一试自己能想出几种解法,如果大家觉得自己的解法也很巧妙,欢迎和我交流~
喝汽水,1瓶汽水1元,2个空瓶可以换一瓶汽水,给20元,可以喝多少汽水。
(在做题时,可以将20换成n)
直接通过简单的数学计算一下,这是最容易想到也是最直接的解法。
代码如下
int main()
{
int money = 0;
int bottle = 0;
int empty = 0;
scanf("%d", &money);
bottle = money;
empty = money;
while (empty > 1)
{
bottle += empty / 2;
empty = (empty / 2) + (empty % 2);
}
printf("%d\n",bottle);
return 0;
}
就是喝一次买一次,喝光了再用剩下的空瓶子兑换新的
int main()
{
int money = 0;
int bottle = 0;
scanf("%d", &money);
if (money > 0)
bottle = 2 * money - 1;
else
bottle = 0;
printf("%d\n", bottle);
return 0;
}
我们可以发现一个数学规律:
钱数与最终能喝到的饮料数的关系为:
bottle = 2 * money - 1;
利用这个表达式,就可以更简单的求出结果
写一个函数返回参数二进制中 1 的个数。
int count_num_of_1(unsigned int n)
{
int count = 0;
while (n)
{
if (n % 2 == 1)
count++;
n /= 2;
}
return count;
}
int main()
{
int num = 0;
scanf("%d", &num);//-1
int ret = count_num_of_1(num);
printf("%d\n", ret);
return 0;
}
很常规也很简单的一种解法,这里就不解释了
int count_num_of_1(int n)
{
int count = 0;
int i = 0;
for (i = 0; i < 32; i++)
{
if (((n >> i) & 1) == 1)
count++;
}
return count;
}
int count_num_of_1(int n)
{
int count = 0;
while (n)
{
n = n & (n - 1);
count++;
}
return count;
}
使用移位操作符,使用二进制来解题,更直观。
善用操作符可能有时候会简化代码
两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同
int count_diff_bit(int m ,int n)
{
int i = 0;
int count = 0;
for (i=0; i<32; i++)
{
if (((m >> i) & 1) != ((n >> i) & 1))
count++;
}
return count;
}
int main()
{
int m = 0;
int n = 0;
scanf("%d %d", &m, &n);
int ret = count_diff_bit(m ,n);
printf("%d\n", ret);
return 0;
}
if语句就是判断在同时右移i个bit位之后,二者这是否相同
int count_diff_bit(int m, int n)
{
int r = m ^ n;
int i = 0;
int count = 0;
while (r)
{
r = r & (r - 1);
count++;
}
return count;
}
int main()
{
int m = 0;
int n = 0;
scanf("%d %d", &m, &n);
int ret = count_diff_bit(m, n);
printf("%d\n", ret);
return 0;
}
两个点异或和while循环中r的计算
异或操作符:对应的二进制位相同为0,相异为1,那m和n的不同的二进制位异或后一定是1
之后数一下r的二进制中1的个数,就是m和n中不同位的个数
因为二进制的数字减1,就一定有一位变为0,所以将r与(r-1)进行按位与操作(&)后即可。
无论是解法一的移位操作还是解法二中的异或操作,其实考察的就是对于操作符是否能熟练运用,个人觉得并无优劣之分,只是分享一下不同的解法。
将一个字符串的内容颠倒过来,并输出。
如:
i am student
输出:
tneduts ma i
下面两种解法,不做比较,但我本人更推荐第二种解法
#include
#include
int main() {
char arr[10001] = { 0 };
gets(arr);
int len = strlen(arr);
int i = 0;
for (i = len - 1; i >= 0; i--)
{
printf("%c", arr[i]);
}
return 0;
}
就是正着输入,倒着打印
int main() {
char arr[10001] = { 0 };
gets(arr);
char* left = arr;
char* right = arr + strlen(arr) - 1;
while (left < right)
{
char tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
printf("%s\n", arr);
return 0;
}
采用双指针的方式,比使用if语句或者其他语句的解法要更高效,但在此就不展示其他解法了。
输入一个值,输出对应的月份天数,这道题有很多种解法,在此只介绍两种,一种简单解法,一种优化解法。
像使用if语句的解法在此就不引入了,(这种解法有点吓人(捂脸))
int is_leap_year(int y)
{
if ((y % 4 == 0 && y % 100 != 0) || (y % 400 == 0))
return 1;
else
return 0;
}
int main()
{
int y = 0;
int m = 0;
while (scanf("%d %d", &y, &m) == 2)
{
int d = 0;
switch (m)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
d = 31;
break;
case 4:
case 6:
case 9:
case 11:
d = 30;
break;
case 2:
d = 28;
}
if (is_leap_year(y) && m == 2)
d++;
printf("%d\n", d);
}
return 0;
}
很简单,在此解释一下多组输入这个问题,因为scanf函数接收数据时,接收一个数据返回值是1,接收两个数据,返回值就是2,所以当输入的数据有两个时,就一直判定。
int is_leap_year(int y)
{
if ((y % 4 == 0 && y % 100 != 0) || (y % 400 == 0))
return 1;
else
return 0;
}
int main()
{
int y = 0;
int m = 0;
int days[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
while (scanf("%d %d", &y, &m) == 2)
{
int d = days[m];
if (is_leap_year(y) && (m == 2))
d++;
printf("%d\n", d);
}
return 0;
}
使用到了数组,还是比较神奇的一种解法,相较于解法一就简单了一些。
打算新开一个系列,关于题目的多种解法的,因为经常在阅读其他人写的代码的时候,就有一种感觉,这个人怎么写的那么好,他怎么想的。
所以就想开一个专栏关于题目解法的优化的,遇到好题记录一下分享给大家,目前暂定也是一篇文章五道题,目前大都是简单题,慢慢来。