1,cf Palindromic Numbers;2,牛牛看云;3,中位数切分;4,cf Another Problem About Dividing Numbers;5,九小时九个人九扇门;
1,cf Palindromic Numbers
题意:给你一个长度为n的正整数,一定存在另一个长度也为n的数,使得他俩的和为回文数;求出另一个数;
思路:看正整数开头的数字,在1~8就可以用长度为n的999....来当回文数,再减去给出的数字,就可得到长度为n的另一个数,如果开头数字是9,那么我选择的是长度为n+1的111....,用到了高精度减法;
高精度减法复习:
(A的长度>B的长度 ,每次存的是(t+10)%10,这样做的好处就是不用特判t<0是否需要借数等,直接在后面特判,t<0,说明需要借1,t=1,这样下一轮t=A[i]-t,就会少1,最后除去前导0的操作);
code:
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define rep1(i,a,n) for( int i=a;i<n;++i)
#define rep2(i,a,n) for( int i=a;i<=n;++i)
#define per1(i,n,a) for( int i=n;i>a;i--)
#define per2(i,n,a) for( int i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define memset(a,i,b) memset((a),(i),sizeof (b))
#define memcpy(a,i,b) memcpy((a),(i),sizeof (b))
#define pro_q priority_queue
#define pb push_back
#define pf push_front
#define endl "\n"
#define lowbit(m) ((-m)&(m))
#define YES cout<<"YES\n"
#define NO cout<<"NO\n"
#define Yes cout<<"Yes\n"
#define No cout<<"No\n"
#define yes cout<<"yes\n"
#define no cout<<"no\n"
#define yi first
#define er second
using namespace std;
typedef pair<long long,long long>PLL;
typedef long long LL;
typedef pair<int,int> PII;
typedef pair<int,PII> PIII;
typedef double dob;
const int N=1e5+10;
char a[N];
vector<int> sub(vector<int>A,vector<int>B)
{
vector<int>C;
int t=0;
int asiz=A.size();
int bsiz=B.size();
rep1(i,0,asiz)
{
t=A[i]-t;
if(i<bsiz)t-=B[i];
C.pb((t+10)%10);
if(t<0)t=1;
else t=0;
}
while(C.size()>1&&C.back()==0)C.pop_back();
return C;
}
void solve()
{
int n;
cin>>n;
rep2(i,1,n)cin>>a[i];
if(a[1]=='9')
{
vector<int>A,B;
rep2(i,1,n+1)A.push_back(1);
per2(i,n,1)B.push_back(a[i]-'0');
auto C=sub(A,B);
int csiz=C.size();
per2(i,csiz-1,0)cout<<C[i];
cout<<endl;
}
else
{
vector<int>A,B;
rep2(i,1,n)A.pb(9);
per2(i,n,1)B.pb(a[i]-'0');
auto C=sub(A,B);
int csiz=C.size();
per2(i,csiz-1,0)cout<<C[i];
cout<<endl;
}
}
signed main()
{
quick_cin();
int T;
cin>>T;
while(T--)solve();
return 0;
}
2,牛牛看云;
思路:直接按公式做肯定是tle的,看序列的数据范围,只有1000,所以可以记录0~1000的每个数的出现次数,然后转换下求法即可;
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define rep1(i,a,n) for( int i=a;i<n;++i)
#define rep2(i,a,n) for( int i=a;i<=n;++i)
#define per1(i,n,a) for( int i=n;i>a;i--)
#define per2(i,n,a) for( int i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define memset(a,i,b) memset((a),(i),sizeof (b))
#define memcpy(a,i,b) memcpy((a),(i),sizeof (b))
#define pro_q priority_queue
#define pb push_back
#define pf push_front
#define endl "\n"
#define lowbit(m) ((-m)&(m))
#define YES cout<<"YES\n"
#define NO cout<<"NO\n"
#define Yes cout<<"Yes\n"
#define No cout<<"No\n"
#define yes cout<<"yes\n"
#define no cout<<"no\n"
#define yi first
#define er second
using namespace std;
typedef pair<long long,long long>PLL;
typedef long long LL;
typedef pair<int,int> PII;
typedef pair<int,PII> PIII;
typedef double dob;
const int N=1e6+10;
LL cs[N];
LL ans;
signed main()
{
quick_cin();
int n;
cin>>n;
rep2(i,1,n)
{
int x;
cin>>x;
cs[x]++;
}
rep2(i,0,1000)
{
LL num=0;
rep2(j,i,1000)
{
if(j==i)num=((cs[i]+1)*cs[i])/2;
else num=cs[i]*cs[j];
ans+=num*abs(i+j-1000);
}
}
cout<<ans;
return 0;
}
3,中位数切分;
数学题:
结论:设cnt1为>=m的数的个数,cnt2为<m的个数,如果cnt1>cnt2,则ans=cnt1-cnt2;否则就是-1;
证明:
设f(l,r)为数组al到ar的cnt1-cnt2的值,很明显f(l,r)>1才是符合要求的区间;
f(l,r)的性质:f(l,r)=f(l,mid)+f(mid+1,r);
要找的就是存在一个位置mid,使得f(l,mid)>0&&f(mid+1,r)>0;
看f(l,mid)=1的情况,此时f(l,r)>1,所以f (mid+1,r)=f(l,r)-f(l,mid)>0,所以此时就可以切;
为了切最多的区间,肯定是f(l,r)=1;
又因为整个在f(1,n)区间进行切割,所以总的和等于f(1,n)=cnt1-cnt2;
code:
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define rep1(i,a,n) for( int i=a;i<n;++i)
#define rep2(i,a,n) for( int i=a;i<=n;++i)
#define per1(i,n,a) for( int i=n;i>a;i--)
#define per2(i,n,a) for( int i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define memset(a,i,b) memset((a),(i),sizeof (b))
#define memcpy(a,i,b) memcpy((a),(i),sizeof (b))
#define pro_q priority_queue
#define pb push_back
#define pf push_front
#define endl "\n"
#define lowbit(m) ((-m)&(m))
#define YES cout<<"YES\n"
#define NO cout<<"NO\n"
#define Yes cout<<"Yes\n"
#define No cout<<"No\n"
#define yes cout<<"yes\n"
#define no cout<<"no\n"
#define yi first
#define er second
using namespace std;
typedef pair<long long,long long>PLL;
typedef long long LL;
typedef pair<int,int> PII;
typedef pair<int,PII> PIII;
typedef double dob;
const int N=1e6+10;
int n,m;
void solve()
{
cin>>n>>m;
int cnt1=0,cnt2=0;
rep2(i,1,n)
{
int x;
cin>>x;
if(x>=m)cnt1++;
else cnt2++;
}
if(cnt1>cnt2)cout<<cnt1-cnt2<<endl;
else cout<<-1<<endl;
}
signed main()
{
quick_cin();
int T;
cin>>T;
while (T--)
{
solve();
}
return 0;
}
4, cf Another Problem About Dividing Numbers
题意:
思路:求出来最小操作次数和最多操作次数即可;对于a=b&&k=1的情况进行特判;
最小操作次数:
a=b,0;
a!=b,a!=gcd(a,b)&&b!=gcd(a,b)时为2,否则为1;
最大操作次数:
a与b的质因数个数之和;
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define rep1(i,a,n) for( int i=a;i<n;++i)
#define rep2(i,a,n) for( int i=a;i<=n;++i)
#define per1(i,n,a) for( int i=n;i>a;i--)
#define per2(i,n,a) for( int i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define memset(a,i,b) memset((a),(i),sizeof (b))
#define memcpy(a,i,b) memcpy((a),(i),sizeof (b))
#define pro_q priority_queue
#define pb push_back
#define pf push_front
#define endl "\n"
#define lowbit(m) ((-m)&(m))
#define YES cout<<"YES\n"
#define NO cout<<"NO\n"
#define Yes cout<<"Yes\n"
#define No cout<<"No\n"
#define yes cout<<"yes\n"
#define no cout<<"no\n"
#define yi first
#define er second
using namespace std;
typedef pair<long long,long long>PLL;
typedef long long LL;
typedef pair<int,int> PII;
typedef pair<int,PII> PIII;
typedef double dob;
const int N=1e6+10;
int a,b,k;
inline int gcd(int a,int b)
{
if(b)while((a%=b)&&(b%=a));
return a+b;
}
int zhi(int num)
{
int ans=0;
for(int i=2;i*i<=num;i++)
{
while(num%i==0)
{
num/=i;
ans++;
}
}
if(num!=1)ans++;
return ans;
}
int xiao(int a,int b)
{
int ans=0;
int num=gcd(a,b);
if(a!=num)ans++;
if(b!=num)ans++;
return ans;
}
int da(int a,int b)
{
return zhi(a)+zhi(b);
}
void solve()
{
cin>>a>>b>>k;
if(xiao(a,b)<=k&&k<=da(a,b)&&(a!=b||k!=1))YES;
else NO;
}
signed main()
{
quick_cin();
int T;
cin>>T;
while (T--)
{
solve();
}
return 0;
}
5,九小时九个人九扇门
题意:
数字根的结论:一个数的数字根是它%9的结果;
一个四位数abcd%9=(a*1000+b*100+c*10+d)%9=(a+b+c+d)%9;
问题转化为: 从a数组中选择一些数字,使得其求和对9取模为0,1,2,3,4,5,6,7,8有多少种选法
最后记得-1,不能一个也不选;
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define rep1(i,a,n) for( int i=a;i<n;++i)
#define rep2(i,a,n) for( int i=a;i<=n;++i)
#define per1(i,n,a) for( int i=n;i>a;i--)
#define per2(i,n,a) for( int i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define memset(a,i,b) memset((a),(i),sizeof (b))
#define memcpy(a,i,b) memcpy((a),(i),sizeof (b))
#define pro_q priority_queue
#define pb push_back
#define pf push_front
#define endl "\n"
#define lowbit(m) ((-m)&(m))
#define YES cout<<"YES\n"
#define NO cout<<"NO\n"
#define Yes cout<<"Yes\n"
#define No cout<<"No\n"
#define yes cout<<"yes\n"
#define no cout<<"no\n"
#define yi first
#define er second
using namespace std;
typedef pair<long long,long long>PLL;
typedef long long LL;
typedef pair<int,int> PII;
typedef pair<int,PII> PIII;
typedef double dob;
const int N=1e6+10;
LL f[N][9];
const int mod=998244353;
signed main()
{
quick_cin();
int n;
cin>>n;
f[0][0]=1;
rep2(i,1,n)
{
int x;
cin>>x;
rep1(j,0,9)
{
f[i][(j+x)%9]=(f[i][(j+x)%9]+f[i-1][j])%mod;
f[i][j]=(f[i][j]+f[i-1][j])%mod;
}
}
rep2(i,1,8)cout<<f[n][i]<<" ";
cout<<f[n][0]-1;
return 0;
}