A - GCD Sum
题意:
第一个多组输入
第二个给你一个数字n,然后让你判断什么时候n和他自己每一个数位的和可以出来gcd大于1
思路:
这里不提供严格的数学证明,我们可以根据几组数据推导可以知道,我们只需要判断n,n+1,n+2这个三个数字即可
感兴趣的师傅们可以推导证明试试
然后我们就可以写代码判断了
AC代码如下
#include<bits/stdc++.h>
#define int long long
using namespace std;
int a[20];
bool solve(int n)
{
memset(a,0,sizeof(a));
int temp=n;
int cnt=1;
while(temp)
{
a[cnt++]=temp%10;
temp/=10;
}
int sum=0;
for(int i=1;i<cnt;i++)
{
sum+=a[i];
}
if(__gcd(n,sum)>1)return true;
else return false;
}
signed main()
{
int T;
scanf("%lld",&T);
while(T--)
{
int n;
scanf("%lld",&n);
if(solve(n))
{
printf("%lld\n",n);
}
else if(solve(n+1))
{
printf("%lld\n",n+1);
}
else if(solve(n+2))
{
printf("%lld\n",n+2);
}
}
return 0;
}
B - Box Fitting
题意:
第一个多组输入
第二个给你n个数字,和二维平面的一个宽度
我们需要判断的是他的最小的高是多少
思路:
首先我们第一个想法肯定是贪心
我们该怎么去贪心这个东西
首先我们要把我们的方块从大到小排一个序
这里我是用的是multiset使他的复杂度为log(n)
然后这个是存我们输入的方块
第二个我用了一个大顶堆的优先队列进行操作
这个我每次先把这个清空吗,然后我push一个0进去
意义就是第一次什么都没有操作的时候的样子,这个存储的是每层剩余的空位置
紧接着我们一个个判断,从我们的multiset的第一个开始判断,如果他小于这个剩余的空位置,我们就可以把它输进去,我们把之前保存的那个空位置直接pop()掉,然后我们紧接着把新的空位置输入进去,什么是新的空位置,就是原来的空位置减去我们刚才输入进去的方块
然后我们紧接着进行下一个方块的判断,如果我们这次的这个方块它如果比我们这层所剩下的空位置要是大的话,我们不得以就是得再开一层来存放我们的这个方块,然后既然我们又开了一层,我们的层数这里我用cnt表示,所以就是cnt++
紧接着我们把我们新开辟的一层存入我们的大顶堆的优先队列里面,这个存入的就是我们的宽度减去我们刚才的那个木块的一个大小,这样我们的思路就完成了,当我们循环完了最后一个方块之后,我们不就是可以知道我们究竟需要几层么,这个就是这个思路,请仔细读完,想明白之后很简单,下面的AC代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10;
//int a[N];
multiset<int,greater<int> >a;// n
priority_queue<int>q;// leave
signed main()
{
int T;
scanf("%lld",&T);
while(T--)
{
a.clear();
while(!q.empty())q.pop();
int temp=q.top();
// printf("%lld\n",temp);
multiset<int,greater<int> >::iterator it;
int n,w;
scanf("%lld%lld",&n,&w);
for(int i=1;i<=n;i++)
{
int temp;
scanf("%lld",&temp);
a.insert(temp);
}
q.push(0);
// for(it=a.begin();it!=a.end();it++)
// printf("%lld ",*it);
int cnt=0;
for(it=a.begin();it!=a.end();it++)
{
int temp=q.top();
q.pop();
if(temp<*it)
{
q.push(temp);
q.push(w-*it);
cnt++;
}
else
{
q.push(temp-*it);
}
}
printf("%lld\n",cnt);
}
return 0;
}