第一次排位赛总结
1.Sky数
方法一:定义一个函数,分别输入n和进制。
int sum(int n,int r)//r是要转换的进制
{
int sum=0;
while(n)
{
sum+=n%r;
n=n/r;
}
return sum;
}
注意
- 进制转换(十进制转十六进制,十进制转12进制)
- 在每个进制下对应位数求和看三者是否相同
- 打印结果(注意格式)
方法二(暴力法):
#include <stdio.h>
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
if(n!=0)
{
int a=n;
int b=n;
int c=n;
int sum1=0;
int sum2=0;
int sum3=0;
while(a)
{
sum1+=(a%10);
a=a/10;
}
while(b)
{
sum2+=(b%12);
b=b/12;
}
while(c)
{
sum3+=(c%16);
c=c/16;
}
if(sum1==sum2&&sum1==sum3)
{
printf("%d is a Sky Number.\n",n);
}
else
{
printf("%d is not a Sky Number.\n",n);
}
}
else{
return 0;
}
}
return 0;
}
2.哥德巴赫来了可能有用吧
- 首先是哥德巴赫猜想:大于2的偶数可以分解成两个素数之和
- 10000以内的素数:素数筛法———用筛法求素数(可以减少时间复杂度)
#include<stdio.h>
int main()
{
int a[10001],n;
for(int i=2;i<=10000;i++)
{
a[i]=i;
}
for(int i=2;i<=5000;i++)
{
for(int j=2*i;j<=10000;j+=i)
{
a[j]=0;
}
}
while(scanf("%d",&n)!=EOF)
{
if(n==0)
break;
int m=0;
for(int i=3;2*i<n;i++)
{
if(a[i]+a[n-i]==n)
m++;
}
printf("%d\n",m);
}
return 0;
}
3.咦!这是嘛呀!
首先了解XOR
- 与运算(&):0&0=0;0&1=0;1&0=0;1&1=1;
- 异或运算(xor):0^0=0; 0^1=1; 1^0=1; 1^1=0;
对于本题
- 如果A&B等于0 那么C可以给最小的0,但是题目要特判,所以为1
- A&B不等于0,那么就需要让C与他们共同为1的一致就好这样能得到最小值
typedef long long 11;
int main()
{
int T;
cin >> T;
ll a,b;
while(T--){
cin>>a>>b;
ll c = a&b;
printf("%lld\n",c?c:1);
}
return 0;
}
4.倩姐的自我突破
此题可以投机取巧,使用暴力的方法。
样例 | 结果 |
---|---|
2 | 1 |
3 | 2 |
4 | 3 |
… | … |
n | n-1 |
5.看看就好,劝一下自己
方法一(暴力求解)
#include <stdio.h>
int main()
{
int m;
scanf("%d",&m);
int i;
int a,b;
for(i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
int j,k;
int count1=0;
int count2=0;
for(j=1;j<a;j++)
{
if(a%j==0)
{
count1=count1+j;
}
}
for(k=1;k<b;k++)
{
if(b%k==0)
{
count2=count2+k;
}
}
if(count1==b&&count2==a)
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
return 0;
}
方法二(约数和打表)
- 这个就是提高了算法效率,就是他不是就是600000以内吗,我把他们的每个数的约数和求出来存在数组就好了
6.熊熊的尝试
- 首先了解巴什博弈(只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个。最后取光者得胜。)
- 思考:最多取m个,如果剩下m+1个是不是无论第一个人如何取,后手都能一次取完
- 也就是说:无论他们前边如何拿如果n=(m+1)r+s(换句话说就是当先手拿走s个时,后手总能保证剩下的为m+1的整数倍,则后手必胜,否则先手必胜)
- 例如:先手拿走s个,后手拿走k个保证剩下的是(m+1)的整数倍,则后手必胜,如果先手拿走s个使得剩下的为(m+1)的整数倍,则先手必胜
- 结论:n % (m+1) == 0,后手必胜;否则先手必胜
#include <stdio.h>
int main()
{
int c,m,n;
scanf("%d",&c);
while(c--)
{
scanf("%d%d",&m,&n);
if(m%(n+1)==0)
{
printf("second\n");
}
else
{
printf("first\n");
}
}
return 0;
}
7.该烂怂塔,有啥看的
思路:从下往上,保证每个局部都是最大值,即最后所得和也是最大值。
例如
- 19和7选择19与2相加,得21
- 7和10选择10与18相加,得28
#include <stdio.h>
int main()
{
int n;
int m;
scanf("%d",&n);
int a[100][100];
int i,j,k;
for(k=0;k<n;k++)
{
scanf("%d",&m);
for(i=0;i<m;i++)
{
for(j=0;j<=i;j++)
{
scanf("%d",&a[i][j]);
}
}
for(i=m-1;i>0;i--)
{
for(j=m-1;j>0;j--)
{
if(a[i][j]>=a[i][j-1])
{
a[i-1][j-1]=a[i-1][j-1]+a[i][j];
}
else
{
a[i-1][j-1]=a[i-1][j-1]+a[i][j-1];
}
}
}
printf("%d\n",a[0][0]);
}
return 0;
}
8.Tyloo的S1mple本人
暴力求解(注意:外层循环从大的开始,减少循环次数)。
#include <stdio.h>
int main()
{
int t;
int i,j,k,l;
int a[10000];
scanf("%d",&t);
for(i=0;i<t;i++)
{
scanf("%d",&a[i]);
}//
for(l=0;l<t;l++)
{
int s=1;
for(i=0;7*i<=a[l];i++)
{
for(j=0;5*j<=a[l];j++)
{
for(k=0;3*k<=a[l];k++)
{
if(3*k+5*j+7*i==a[l])
{
s=0;
break;
}
}
if(3*k+5*j+7*i==a[l])
{
s=0;
break;
}
}
if(3*k+5*j+7*i==a[l])
{
s=0;
break;
}
}
if(s==0)
{
printf("%d %d %d \n",k,j,i);
}
else if(s==1)
{
printf("-1\n");
}
}
return 0;
}
9.可鞥吧
此题的思想是贪心。
#include <stdio.h>
int main()
{
int t;
int i,n,k;
scanf("%d",&t);
for(i=0;i<t;i++)
{
int temp;
int max=0;
int l;
scanf("%d%d",&n,&k);
int j;
int a[1000];
for(j=0;j<n;j++)
{
scanf("%d",&a[j]);
}
for(j=0;j<n-1;j++) //可以直接使用sort含数
{
for(l=0;l<n-1-j;l++)
{
if(a[l]<a[l+1])
{
temp=a[l+1];
a[l+1]=a[l];
a[l]=temp;
}
}
}
for(j=0;j<=k;j++)
{
max=max+a[j];
}
if(k==0) //注意考虑k=0的情况
{
printf("%lld\n",a[n-1]-a[0]);
}
else
{
printf("%lld\n",max);
}
}
return 0;
}
10.最后是啥呢
- 首先明确最后最小值的结果一定是2
#include <stdio.h>
int main()
{
int m,n;
scanf("%d",&m);
int a[200000];
for(int i=0;i<m;i++)
{
int k=1;
int q=3;
scanf("%d",&n);
for(int j=0;j<n;j++)
{
a[j]=k++;
}
printf("2\n");
for(int j=0;j<n-1;j++)
{
printf("%d %d\n",a[n-q+1],a[n-q+2]);
if((a[n-q+1]+a[n-q+2])%2!=0)
{
a[n-q+1]=((a[n-q+1]+a[n-q+2])/2)+1;
}
else
{
a[n-q+1]=((a[n-q+1]+a[n-q+2])/2);
}
q++;
}
}
return 0;
}