题意:给你两个正多边形的边数,问第二个正多边形能不能嵌套在第一个正多边形内
1.顶点必须对顶点 2.两个正多边形中心重合
题解:如果第一个正多边形的边数能整除第二个正多边形的条数 就可以满足嵌套
code:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<set>
#include<sstream>
using namespace std;
typedef long long ll;
const ll maxn=1e6+10;
const ll inf=0x3f3f3f3f3f3f3f3f;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
ll n;
cin>>n;
while(n--)
{
ll n,m;
cin>>n>>m;
if(n%m==0)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}
题意:给你一个数组a,当 i<j时 满足 j - a[j] ≠ i - a[i] ,让你写出一个满足的数组序列
题解:下标是从小到大的,我们把序列从大到小排序,这样 下标 - 数组的值 永远不会相等,可以这样想,下标是从最小开始,数组从最大开始,差值肯定是最下的,遍历数组肯定差值会单调递增的。
code:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<set>
#include<sstream>
using namespace std;
typedef long long ll;
const ll maxn=1e6+10;
const ll inf=0x3f3f3f3f3f3f3f3f;
ll a[110];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
ll t;
cin>>t;
while(t--)
{
ll n;
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
sort(a,a+n);
for(int i=n-1;i>=0;i--)
cout<<a[i]<<" ";
cout<<'\n';
}
return 0;
}
题意:给你一个n、k和一个num数组,让你从一个全为0的数组走i步能不能得到num数组:
对于第i步 1.走 任意给一个数 增加k^i
2.不走 不操作任何数
题解:看到k^ i 很敏感的想到了k进制数的第i位为1 , 每一步只能走1次,所以k^i只能任意增加1次。
把num数组的所有数转化成k进制,num数组的所有数的k进制数的每一个第j位(0<=j<=最大位数)总和最大为1(保证只走1次或不走,保证他只增加k^i )可以满足题意输出YES ,否则输出NO
code:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<set>
#include<sstream>
using namespace std;
typedef long long ll;
const ll maxn=1e6+10;
const ll inf=0x3f3f3f3f3f3f3f3f;
ll a[110];
ll num[110],vis[110];
void tranf(ll n,ll r)
{
for(ll i=0;i<55;i++)
{
a[i]=(ll)n%(ll)r;
n/=(ll)r;
if(n==0)
{
break;
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
ll t;
cin>>t;
while(t--)
{
ll n,k,o=0;
cin>>n>>k;
for(ll j=0;j<=55;j++)
vis[j]=0;
for(ll i=0;i<n;i++)
cin>>num[i];
ll p=0;
for(ll i=0;i<n;i++)
{
for(int q=0;q<55;q++)
a[q]=0;
if(p)
break;
tranf((ll)num[i],k);
for(ll j=0;j<55;j++)
{
if(a[j])
{
vis[j]+=a[j];
if(vis[j]>1)
{
p=1;
break;
}
}
}
}
if(p) cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
return 0;
}
题意: 给你一个n和m,让你从[1,m]里任意挑选数,组成长度为n的数组kk
数组kk满足 1.有且仅由1对相同的数
2.第i个数为最大值,i前面的所有数严格递增,i后面的所有数严格递减。
题解: C( m , n-1 )* (n-2) * 2^(n-3)
长度为n的数组他有n-1个不同的数(因为条件1、2限制),所以我们要在m个数里挑选数n-1个不同的数来组成长度n,-------> C( m , n-1 )
条件1的限制,n-1个数里肯定会有一个最大值,这个就是数组kk的第i位,剩下的n-2个数每一位都有可能出现一个跟他相同的数组成长度为n的数组。---->C( m , n-1 )* (n-2)
条件2,我们已经把最大值和一对相同的数安排好位置(一对相同的数在最大值的两侧),剩下n-3个数该怎么排位置呢? 每个数都可以放在最大值的左侧或右侧,有2种选择,n-3个数不就是 2^(n-3) 种位置!-------> C( m , n-1 )* (n-2) * 2^(n-3)
code:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<set>
#include<sstream>
using namespace std;
typedef long long ll;
const ll maxn=2e5+10;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=998244353;
ll f[maxn];
ll quick_pow(ll a,ll b)
{
ll temp=a%mod,ans=1;
while(b)
{
if(b&1)
ans=(ans*temp)%mod;
temp=(temp*temp)%mod;
b>>=1;
}
return ans%mod;
}
ll ni(ll a)
{
return quick_pow(a,mod-2);
}
void pre()
{
f[0]=1;
for(int i=1;i<maxn;i++)
{
f[i]=(f[i-1]*i)%mod;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
pre();
ll n,m;
cin>>n>>m;
if(n==2)
cout<<0<<endl;
else
cout<<((f[m]*ni(f[n-1]%mod*f[m-n+1])%mod*(n-2))%mod*quick_pow(2,n-3))%mod<<'\n';
return 0;
}