1.J题:将一个十进制的数字转换成二进制(共32位),分成4部分(每部分8位),求给出的每一个数字里的四部分一共有多少个“1100001”。
刚开始的思路是将所给的数字转换成二进制的形式,然后存到字符串中,最后从后往前遍历字符串每找到一次“1000011”数量就加一,然后超时了。
后来看了题解提交的时候还是超时,原因是我把输入的每个数字存入到了数组里面,改为存入一个变量就行了
正确的思路:通过位运算将数字的每部分与256(2的8次方)取余,如果等于97,数量就加一。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
ll k,m;
int i,j,n;
ll a[200];
while(cin>>n)
{
ll num=0;
for(i=0;i<n;i++)
{
cin>>k;
for(j=0;j<4;j++)
{
if(k%256==97)
{
num++;
}
k>>=8;
}
}
cout<<num<<endl;
}
return 0;
}
2.D题:
正确思路:数学公式计算。设x、y最大公因数是g,最小公倍数是l,那么x*y=g*l,
x=i*g
y=j*g
很容易看出i、g一定互为质数,所以i+g,i*g也互为质数,x+y=(i*g)+(j*g)=g(i+j)=a
x*y=i*j*g*g=b*g,故b=i*j*g,所以g也是a,b的最大公因数,用求根公式解方程组:
x+y=a
x*y=b*g
就行了
写代码的时候出了点问题,一直WA,后来发现是sqrt()函数的返回值是浮点型的原因
代码:
#include<bits//stdc++.h>
using namespace std;
typedef long long ll;
int f(int a,int b)
{
return a==b?a:a>b?f(a-b,b):f(a,b-a);
}
int main()
{
int x,y,a,b,i,j;
while(scanf("%d%d",&a,&b)!=EOF)
{
ll n,k;
k=f(a,b);
n=k*b;
int der=a*a-4*n;
if(der<0)
{
cout<<"No Solution"<<endl;
continue;
}
int qrt=sqrt(der);
if(qrt*qrt!=der)
{
cout<<"No Solution"<<endl;
continue;
}
y=(a-qrt)/2;
x=a-y;
cout<<y<<' '<<x<<endl;
}
return 0;
}
3.H题:
主要是高中学过的概率计算忘得差不多了。
以有两个黑球,一个红球为例,第一次摸摸到红球的概率是:1/3
第二次:(1-1/3)*1/2=1/3
第三次:(1-1/3)*(1-1/2)*1=1/3
多举几个例子,会发现,不管有多少黑球,每次抽的概率都是一样的,也就是说,抽到红球的概率仅仅与抽的次数有关。在先手的情况下,黑球的次数为奇数时,抽的次数多,偶数抽的次数相同,所以代码简单到爆:
#include <iostream>
#include <cmath>
using namespace std;
int main(){
int i,j,k;
while(cin>>k)
{
if(k&1)
{
cout<<0<<endl;
}
else
{
cout<<1<<endl;
}
}
return 0;
}