A. Don't Try to Count
题目:
思路:模拟即可,加倍字符串x,然后用find函数查找。
代码:
void solve(){
int n,m;cin>>n>>m;
string x,s;cin>>x>>s;
if(x.find(s)!=-1){
cout<<0<<endl;return;
}
for(int i=1;x.size()<=n*m;i++){
x+=x;
if(x.find(s)!=-1){
cout<<i<<endl;return;
}
}
cout<<-1<<endl;
}
B. Three Threadlets
题目:
思路:先排个序,然后由于最后线的长度相同,那么两条长的一定的那条最短的长度的倍数,然后算出那个倍数x,操作x-1次,看是否超过3.
代码:
void solve(){
vector<int>a(3);
cin>>a[0]>>a[1]>>a[2];
sort(a.begin(),a.end());
if(a[0]==a[2]){
cout<<"YES"<<endl;return;
}
if(a[1]%a[0]||a[2]%a[0]){
cout<<"NO"<<endl;return;
}
int cnt=0;
cnt+=a[1]/a[0]-1;
cnt+=a[2]/a[0]-1;
if(cnt>3){
cout<<"NO"<<endl;
}else{
cout<<"YES"<<endl;
}
}
C. Perfect Square
题目:
思路:
我们可以发现,左上左下右上右下四块旋转后会重合。我们比较四块的值即可,每四个字符,把他们都变成最大的那个字符即可。
代码:
char a[1010][1010];
void solve(){
int n;cin>>n;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cin>>a[i][j];
}
}
int ans=0;
for(int i=0;i<n/2;i++){
for(int j=0;j<n/2;j++){
int x=i,y=j;
int ma=-1;
for(int k=0;k<4;k++){
ma=max(ma,(int)a[x][y]);
int t=x;
x=y;
y=n-t-1;
}
x=i,y=j;
for(int k=0;k<4;k++){
ans+=ma-a[x][y];
int t=x;
x=y;
y=n-t-1;
}
}
}
cout<<ans<<endl;
}
D. Divide and Equalize
题目:
思路:我们知道,最后数组的每一个元素都相同。那么最后每个元素的质因子的种类个数也一定相同,所以我们把数组的所有质因子存起来,然后分配给n个元素,如果不能分配给n个元素,即某一类质因子个数不能整除n,那么no,否则yes。
代码:
void solve(){
int n;cin>>n;
vector<int>a(n),b(n);
for(int i=0;i<n;i++)
cin>>a[i],b[i]=a[i];
map<int,int>mp;
for(int i=0;i<n;i++){
int x=a[i];
for(int i = 2; i <= x / i; i ++){
if(x % i == 0){
int s = 0;
while(x % i == 0){
s ++;
x /= i;
}
mp[i]+=s;
}
}
if(x > 1) mp[x]++;
}
for(auto [x,y]:mp){
if(y%n){
cout<<"NO"<<endl;
return;
}
}
cout<<"YES"<<endl;
}
E. Block Sequence
题目:
思路:动态规划
我们发现前面的状态取决于后面 ,我们从后往前遍历即可。
dp[i]表示,删除i--n之间的元素个数。
我们可以删除第i个:dp[i]=dp[i+1]+1,对答案贡献1;
我们可以不删除第i个:让第i个作为区间的起点,dp[i]=min(dp[i],dp[i+a[i]+1]);
代码:
void solve(){
int n;cin>>n;
vector<int>a(n);
for(int i=0;i<n;i++)
cin>>a[i];
vector<int>dp(n+1,n);
dp[n]=0;
for(int i=n-1;i>=0;i--){
dp[i]=dp[i+1]+1;//删除第i个
if(i+a[i]<n){
dp[i]=min(dp[i],dp[i+a[i]+1]);//用第i个作为区间的起点
}
}
cout<<dp[0]<<endl;
}