A:给你一首歌,时间为T,每q时间下载q-1秒的歌,先下载了s秒,如果歌还没下完,而且放到了还没有下载到的地方,就重新放一次。问要放几次。
思路:等价于每秒下载(q-1)/q的歌,假设在t秒可以跟上进度,由于已经下了s秒,有:s+(q-1)*t/q=t 然后有t=q*s,每次更新t,然后与T比较大小就好了。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int s,a,q;
cin>>s>>a>>q;
int ans=1;
while(1)
{
a=a*q;
if(a>=s) break;
ans++;
}
cout<<ans<<endl;
return 0;
}
B:N个数,求尽可能少的改变元素使得N个元素构成一个1-N的排列,输出这个排列。
思路:标记已经出现的(1次就好),剩下重复出现的和非法的,按顺序把没出现的填一下就好了。。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
int use[100005];
int a[100005];
int n;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
if(a[i]<=n&&use[a[i]]==0)
{
use[a[i]]=i;
}
}
int k=1;
for(int i=1;i<=n;i++)
{
if(use[a[i]]!=i)
{
while(use[k]) k++;
a[i]=k;
k++;
}
}
for(int i=1;i<=n;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
return 0;
}
C:定义pi(n)是不超过n的素数个数,r(n)是不超过n的回文数个数,给你p/q问你满足:pi(n)<=(p/q)*r(n)的最大的n是多少。
思路:先避免浮点失精度,原问题变成q*pi(n)<=p*r(n)
因为p/q很小,所以直接预处理出当前n的回文数和素数的个数然后扫过去就好了。表打大一点。。。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
const long long maxn=1300000+5;
bool is_prime[maxn];
long long cntpr[maxn];
long long cntpa[maxn];
bool is_pa[maxn];
bool pd(long long num)
{
long long o = num;
long long tmp = 0;
while(num != 0)
{
tmp *= 10;
tmp += num % 10;
num /= 10;
}
if(tmp == o)
return true;
return false;
}
void dabiao()
{
is_prime[0]=is_prime[1]=1;
for(long long i=2;i<=maxn;i++)
{
if(is_prime[i]==1)
{
continue;
}
for(long long j=i*i;j<=maxn;j+=i)
{
is_prime[j]=1;
}
}
}
int main()
{
dabiao();
for(long long i=2;i<=maxn;i++)
{
is_pa[i]=pd(i);
}
cntpa[1]=1;
for(long long i=2;i<=maxn;i++)
{
cntpr[i]=cntpr[i-1]+!is_prime[i];
cntpa[i]=cntpa[i-1]+is_pa[i];
}
long long p,q;
cin>>p>>q;
long long pos=-1;
for(long long i=1;i<=maxn;i++)
{
if(q*cntpr[i]<=p*cntpa[i])
{
pos=i;
}
}
if(pos!=-1)
{
cout<<pos<<endl;
}
else
{
cout<<"Palindromic tree is better than splay tree"<<endl;
}
return 0;
}
D:给你1-N,N个元素构成的集合,求满足对称性传递性并且不满足自反性的集合个数。
思路:找规律然后OEIS。。。。 样例给了1 2 3对应的是1 3 10 分析出4是37,直接上OEIS,搜出答案就是贝尔三角形中的某个特定位置的数,打出贝尔三角形,然后直接过了。。。具体应该是个集合划分的DP,然后纱布不会正确的推法。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
const long long mod=(long long)(1e9+7);
long long dp[4005][4005];
int main()
{
int n;
cin>>n;
dp[0][0]=1;
for(int i=1;i<=n;i++)
{
dp[i][0]=dp[i-1][i-1];
for(int j=1;j<=i;j++)
{
dp[i][j]=(dp[i][j-1]+dp[i-1][j-1])%mod;
}
}
cout<<dp[n][n-1]<<endl;
}
E:2-sat 鑫神的菜。。。