目录
A. Don't Try to Count
Solution:根据题意模拟。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#include <stack>
#include <unordered_map>
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<LL,LL> PII;
const int N = 2e5+10;
const int inf = 0x3f3f3f3f;
const double pi = acos(-1);
template <int T>
struct ModInt {
const static int MD = T;
int x;
ModInt(LL x = 0)
: x(x % MD) {}
int get() { return x; }
ModInt operator+(const ModInt& that) const {
int x0 = x + that.x;
return ModInt(x0 < MD ? x0 : x0 - MD);
}
ModInt operator-(const ModInt& that) const {
int x0 = x - that.x;
return ModInt(x0 < MD ? x0 + MD : x0);
}
ModInt operator*(const ModInt& that) const {
return ModInt((long long)x * that.x % MD);
}
ModInt operator/(const ModInt& that) const {
return *this * that.inverse();
}
void operator+=(const ModInt& that) {
x += that.x;
if (x >= MD)
x -= MD;
}
void operator-=(const ModInt& that) {
x -= that.x;
if (x < 0)
x += MD;
}
void operator*=(const ModInt& that) { x = (long long)x * that.x % MD; }
void operator/=(const ModInt& that) { *this = *this / that; }
ModInt inverse() const {
int a = x, b = MD, u = 1, v = 0;
while (b) {
int t = a / b;
a -= t * b;
std::swap(a, b);
u -= t * v;
std::swap(u, v);
}
if (u < 0)
u += MD;
return u;
}
friend ostream& operator<<(ostream& os, ModInt x) {
os << x.get();
return os;
}
};//全局变量记得清零!
const int mod=998244353;
typedef ModInt<mod> mint;
LL gcd(LL a, LL b)
{
return b ? gcd(b, a % b) : a;
}
bool check(string x,string y){
int len=y.size();
for(int i=0;i+len-1<x.size();i++){
if(x.substr(i,len)==y) return 1;
}
return 0;
}
void solve()
{
int n,m;cin>>n>>m;
string s,t;cin>>s>>t;
int cnt=0;
for(int i=0;i<7;i++){
if(check(s,t)){
cout<<cnt<<'\n';
return;
}else{
cnt++;
s+=s;
}
}
cout<<-1<<'\n';
}
int main()
{
ios::sync_with_stdio(0); cin.tie(0),cout.tie(0);
int t;cin>>t;
while(t--) solve();
}
B. Three Threadlets
Solution:只能分成3,4,5,6份,最优的选择是最小的不会再被分,然后看能否全分成最小值能不能分成六份以内即可。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#include <stack>
#include <unordered_map>
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<LL,LL> PII;
const int N = 2e5+10;
const int inf = 0x3f3f3f3f;
const double pi = acos(-1);
template <int T>
struct ModInt {
const static int MD = T;
int x;
ModInt(LL x = 0)
: x(x % MD) {}
int get() { return x; }
ModInt operator+(const ModInt& that) const {
int x0 = x + that.x;
return ModInt(x0 < MD ? x0 : x0 - MD);
}
ModInt operator-(const ModInt& that) const {
int x0 = x - that.x;
return ModInt(x0 < MD ? x0 + MD : x0);
}
ModInt operator*(const ModInt& that) const {
return ModInt((long long)x * that.x % MD);
}
ModInt operator/(const ModInt& that) const {
return *this * that.inverse();
}
void operator+=(const ModInt& that) {
x += that.x;
if (x >= MD)
x -= MD;
}
void operator-=(const ModInt& that) {
x -= that.x;
if (x < 0)
x += MD;
}
void operator*=(const ModInt& that) { x = (long long)x * that.x % MD; }
void operator/=(const ModInt& that) { *this = *this / that; }
ModInt inverse() const {
int a = x, b = MD, u = 1, v = 0;
while (b) {
int t = a / b;
a -= t * b;
std::swap(a, b);
u -= t * v;
std::swap(u, v);
}
if (u < 0)
u += MD;
return u;
}
friend ostream& operator<<(ostream& os, ModInt x) {
os << x.get();
return os;
}
};//全局变量记得清零!
const int mod=998244353;
typedef ModInt<mod> mint;
LL gcd(LL a, LL b)
{
return b ? gcd(b, a % b) : a;
}
void solve()
{
LL a ,b,c;cin>>a>>b>>c;
map<LL,LL>mp;
LL s=a+b+c;
LL x=min({a,b,c});
if(s%3!=0&s%4!=0&&s%5!=0&&s%6!=0){
cout<<"No"<<'\n';
return;
}
if(!(a%x==0&&b%x==0&&c%x==0)){
cout<<"No"<<"\n";
return;
}
int cnt=a/x+b/x+c/x-3;
if(cnt<=3){
cout<<"Yes"<<'\n';
}else cout<<"No"<<"\n";
}
int main()
{
ios::sync_with_stdio(0); cin.tie(0),cout.tie(0);
int t;cin>>t;
while(t--) solve();
}
C. Perfect Square
Solution:根据题意模拟,记录每个位置旋转四次的最大字母值即可。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#include <stack>
#include <unordered_map>
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<LL,LL> PII;
const int N = 2e5+10;
const int inf = 0x3f3f3f3f;
const double pi = acos(-1);
template <int T>
struct ModInt {
const static int MD = T;
int x;
ModInt(LL x = 0)
: x(x % MD) {}
int get() { return x; }
ModInt operator+(const ModInt& that) const {
int x0 = x + that.x;
return ModInt(x0 < MD ? x0 : x0 - MD);
}
ModInt operator-(const ModInt& that) const {
int x0 = x - that.x;
return ModInt(x0 < MD ? x0 + MD : x0);
}
ModInt operator*(const ModInt& that) const {
return ModInt((long long)x * that.x % MD);
}
ModInt operator/(const ModInt& that) const {
return *this * that.inverse();
}
void operator+=(const ModInt& that) {
x += that.x;
if (x >= MD)
x -= MD;
}
void operator-=(const ModInt& that) {
x -= that.x;
if (x < 0)
x += MD;
}
void operator*=(const ModInt& that) { x = (long long)x * that.x % MD; }
void operator/=(const ModInt& that) { *this = *this / that; }
ModInt inverse() const {
int a = x, b = MD, u = 1, v = 0;
while (b) {
int t = a / b;
a -= t * b;
std::swap(a, b);
u -= t * v;
std::swap(u, v);
}
if (u < 0)
u += MD;
return u;
}
friend ostream& operator<<(ostream& os, ModInt x) {
os << x.get();
return os;
}
};//全局变量记得清零!
const int mod=998244353;
typedef ModInt<mod> mint;
LL gcd(LL a, LL b)
{
return b ? gcd(b, a % b) : a;
}
void solve()
{
int n;cin>>n;
char mp[n][n];
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cin>>mp[i][j];
}
}
LL sum=0;
map<char,int>mp1;
for(int i=0;i<n/2;i++){
for(int j=i;j<n-i-1;j++){
char mx=mp[i][j];map<char,int>mp1;
mx=max({mp[i][j],mp[n-1-j][i],mp[n-1-i][n-1-j],mp[j][n-1-i]});
//cout<<mp[i][j]<<mp[j][n-1-i]<<mp[n-1-i][n-1-j]<<mp[n-1-j][i]<<"\n";
mp1[mp[i][j]]++;
mp1[mp[n-1-j][i]]++;
mp1[mp[n-1-i][n-1-j]]++;
mp1[mp[j][n-1-i]]++;
int cnt=0;
//cout<<mx<<'\n';
for(char k='a';k<='z';k++){
if(mp1[k]&&k!=mx){
//cout<<k<<'\n';
sum+=(mx-k)*mp1[k];
cnt+=(mx-k)*mp1[k];
}
}
//cout<<cnt<<'\n';
}
}
cout<<sum<<'\n';
}
int main()
{
ios::sync_with_stdio(0); cin.tie(0),cout.tie(0);
int t;cin>>t;
while(t--) solve();
}
D. Divide and Equalize
Solution:因为每个数的质因数分解具有唯一性,因此把数组每个数质因数分解记录出现次数即可。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#include <stack>
#include <unordered_map>
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<LL,LL> PII;
const int N = 2e5+10;
const int inf = 0x3f3f3f3f;
const double pi = acos(-1);
template <int T>
struct ModInt {
const static int MD = T;
int x;
ModInt(LL x = 0)
: x(x % MD) {}
int get() { return x; }
ModInt operator+(const ModInt& that) const {
int x0 = x + that.x;
return ModInt(x0 < MD ? x0 : x0 - MD);
}
ModInt operator-(const ModInt& that) const {
int x0 = x - that.x;
return ModInt(x0 < MD ? x0 + MD : x0);
}
ModInt operator*(const ModInt& that) const {
return ModInt((long long)x * that.x % MD);
}
ModInt operator/(const ModInt& that) const {
return *this * that.inverse();
}
void operator+=(const ModInt& that) {
x += that.x;
if (x >= MD)
x -= MD;
}
void operator-=(const ModInt& that) {
x -= that.x;
if (x < 0)
x += MD;
}
void operator*=(const ModInt& that) { x = (long long)x * that.x % MD; }
void operator/=(const ModInt& that) { *this = *this / that; }
ModInt inverse() const {
int a = x, b = MD, u = 1, v = 0;
while (b) {
int t = a / b;
a -= t * b;
std::swap(a, b);
u -= t * v;
std::swap(u, v);
}
if (u < 0)
u += MD;
return u;
}
friend ostream& operator<<(ostream& os, ModInt x) {
os << x.get();
return os;
}
};//全局变量记得清零!
const int mod=998244353;
typedef ModInt<mod> mint;
LL gcd(LL a, LL b)
{
return b ? gcd(b, a % b) : a;
}
void solve()
{
int n;cin>>n;
vector<int>ans(n);
map<int,int>mp;
int mx=-inf,mx1=-inf;
set<int>s;
for(int i=0;i<n;i++) {
cin>>ans[i];
int x=ans[i];
mx1=max(mx1,ans[i]);
for(int i=2;i<=x/i;i++){
if(x%i==0){
int cnt=0;
while(x%i==0){
cnt++;
x/=i;
}
mp[i]+=cnt;
s.insert(i);
mx=max(mx,i);
}
}
if(x>1) mp[x]++,s.insert(x);
}
for(auto t:s){
if(mp[t]%n!=0){
cout<<"No"<<'\n';
return;
}
}
cout<<"Yes"<<'\n';
}
int main()
{
ios::sync_with_stdio(0); cin.tie(0),cout.tie(0);
int t;cin>>t;
while(t--) solve();
}
E. Block Sequence
Solution:经典dp,每一位删除或者不删除,dp[i]代表以i为开头的最小删除次数,如果删除的话那么dp[i]=dp[i+1]+1,如果ans[i]<n-i,dp[i]=min(dp[i],dp[i+ans[i]+1]),最终答案为dp[0]。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#include <stack>
#include <unordered_map>
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<LL,LL> PII;
const int N = 2e5+10;
const int inf = 0x3f3f3f3f;
const double pi = acos(-1);
template <int T>
struct ModInt {
const static int MD = T;
int x;
ModInt(LL x = 0)
: x(x % MD) {}
int get() { return x; }
ModInt operator+(const ModInt& that) const {
int x0 = x + that.x;
return ModInt(x0 < MD ? x0 : x0 - MD);
}
ModInt operator-(const ModInt& that) const {
int x0 = x - that.x;
return ModInt(x0 < MD ? x0 + MD : x0);
}
ModInt operator*(const ModInt& that) const {
return ModInt((long long)x * that.x % MD);
}
ModInt operator/(const ModInt& that) const {
return *this * that.inverse();
}
void operator+=(const ModInt& that) {
x += that.x;
if (x >= MD)
x -= MD;
}
void operator-=(const ModInt& that) {
x -= that.x;
if (x < 0)
x += MD;
}
void operator*=(const ModInt& that) { x = (long long)x * that.x % MD; }
void operator/=(const ModInt& that) { *this = *this / that; }
ModInt inverse() const {
int a = x, b = MD, u = 1, v = 0;
while (b) {
int t = a / b;
a -= t * b;
std::swap(a, b);
u -= t * v;
std::swap(u, v);
}
if (u < 0)
u += MD;
return u;
}
friend ostream& operator<<(ostream& os, ModInt x) {
os << x.get();
return os;
}
};//全局变量记得清零!
const int mod=998244353;
typedef ModInt<mod> mint;
LL gcd(LL a, LL b)
{
return b ? gcd(b, a % b) : a;
}
void solve()
{
int n;cin>>n;
vector<int>ans(n),dp(n+1,n);
for(int i=0;i<n;i++) cin>>ans[i];
dp[n]=0;
for(int i=n-1;i>=0;i--){
dp[i]=dp[i+1]+1;
if(ans[i]<n-i){
dp[i]=min(dp[i],dp[i+ans[i]+1]);
}
}
cout<<dp[0]<<'\n';
}
int main()
{
ios::sync_with_stdio(0); cin.tie(0),cout.tie(0);
int t;cin>>t;
while(t--) solve();
}
F. Minimum Maximum Distance
Solution:题意为给定一颗树,定义f[i]为点i到其它被标记点的最大值,求出minf[i](1<=i<=n)。因为一定存在最远的被标记的两个点,因此最小值一定是最远的两个点距离除2并向上取整。因此两次bfs即可。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#include <stack>
#include <unordered_map>
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<LL,LL> PII;
const int N = 2e5+10;
const int inf = 0x3f3f3f3f;
const double pi = acos(-1);
template <int T>
struct ModInt {
const static int MD = T;
int x;
ModInt(LL x = 0)
: x(x % MD) {}
int get() { return x; }
ModInt operator+(const ModInt& that) const {
int x0 = x + that.x;
return ModInt(x0 < MD ? x0 : x0 - MD);
}
ModInt operator-(const ModInt& that) const {
int x0 = x - that.x;
return ModInt(x0 < MD ? x0 + MD : x0);
}
ModInt operator*(const ModInt& that) const {
return ModInt((long long)x * that.x % MD);
}
ModInt operator/(const ModInt& that) const {
return *this * that.inverse();
}
void operator+=(const ModInt& that) {
x += that.x;
if (x >= MD)
x -= MD;
}
void operator-=(const ModInt& that) {
x -= that.x;
if (x < 0)
x += MD;
}
void operator*=(const ModInt& that) { x = (long long)x * that.x % MD; }
void operator/=(const ModInt& that) { *this = *this / that; }
ModInt inverse() const {
int a = x, b = MD, u = 1, v = 0;
while (b) {
int t = a / b;
a -= t * b;
std::swap(a, b);
u -= t * v;
std::swap(u, v);
}
if (u < 0)
u += MD;
return u;
}
friend ostream& operator<<(ostream& os, ModInt x) {
os << x.get();
return os;
}
};//全局变量记得清零!
const int mod=998244353;
typedef ModInt<mod> mint;
LL gcd(LL a, LL b)
{
return b ? gcd(b, a % b) : a;
}
void solve()
{
int n,k;cin>>n>>k;
vector<bool>mk(n+1);
int temp;
for(int i=0;i<k;i++) {
cin>>temp;
mk[temp]=1;
}
int a,b;
vector<int>v[n+1];
for(int i=0;i<n-1;i++){
cin>>a>>b;
v[a].push_back(b),v[b].push_back(a);
}
queue<int>q;
vector<bool>vis(n+1);
q.push(1);int res=1;
while(!q.empty()){
auto t=q.front();
q.pop();
vis[t]=1;
for(auto x:v[t]){
if(!vis[x]){
vis[x]=1;
q.push(x);
if(mk[x]) res=x;
}
}
}
vis=vector<bool>(n+1);
q.push(res);vector<int>dis(n+1);
vis[res]=1;int ans=0;
while(!q.empty()){
auto t=q.front();
q.pop();
vis[t]=1;
for(auto x:v[t]){
if(!vis[x]){
vis[x]=1;
q.push(x);
dis[x]=dis[t]+1;
if(mk[x]) ans=max(ans,dis[x]);
}
}
}
cout<<(ans+1)/2<<'\n';
}
int main()
{
ios::sync_with_stdio(0); cin.tie(0),cout.tie(0);
int t;cin>>t;
while(t--) solve();
}