A - Strange Table
思路
这个就是根据第一个矩阵来求出这个点的横坐标和纵坐标。
我当时推的就是
l
=
x
l=x%n
l=x
r
=
(
x
−
l
)
/
n
+
1
r=(x-l)/n+1
r=(x−l)/n+1
这个点x的坐标就是(l,r)。
然后根据第二个矩阵的性质求出最终结果。
代码
#include <bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define me memset
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
int main()
{
int t;
cin>>t;
while(t--)
{
ll n,m,x;
cin>>n>>m>>x;
ll x1=x%n;
if(x1==0) x1=n;
ll y1=(x-x1)/n+1;
// cout<<x1<<" "<<y1<<endl;
ll c=(x1-1)*m+(y1);
cout<<c<<endl;
}
return 0;
}
B - Partial Replacement
思路
这就是一个模拟题,没什么好说的。
代码
#include <bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define me memset
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
int main()
{
int t;
cin>>t;
while(t--)
{
int n,k;
cin>>n>>k;
string s;
cin>>s;
int flag1=0;
for(int i=0 ; i<s.length() ; i++)
{
if(s[i]=='*')
{
flag1=i;
break;
}
}
int flag2=0;
for(int i=s.length()-1 ; i>=0 ; i--)
{
if(s[i]=='*')
{
flag2=i;
break;
}
}
if(flag1==flag2)
{
cout<<"1"<<endl;
continue;
}
int ans=0;
s[flag1]='x';
s[flag2]='x';
ans+=2;
for(int i=0 ; i<s.length() ; i++)
{
if(s[i]=='x')
{
bool flag=false;
int c=0;
if(i+k>=n) c=n;
else c=i+k;
for(int j=i+1 ; j<=c ; j++)
{
if(s[j]=='x')
{
flag=true;
break;
}
}
if(flag) continue;
else
{
for(int j=c ; j>=i+1 ; j--)
{
if(s[j]=='*')
{
s[j]='x';
ans++;
break;
}
}
}
}
}
cout<<ans<<endl;
}
return 0;
}
C - Double-ended Strings
思路
这个题就是求两个字符串的最长公共字串,昨天晚上一直WA了两发,最后才发现原来边界问题没有考虑到。
#include <bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define me memset
const int N = 100;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
int dp[N][N];
int main()
{
int t;
cin>>t;
while(t--)
{
memset(dp,0,sizeof dp);
string s1,s2;
cin>>s1>>s2;
int ans=0;
for(int i=0 ; i<s1.length() ; i++)
{
for(int j=0 ; j<s2.length() ; j++)
{
if(s1[i]==s2[j])
{
if(i==0&&j==0) dp[i][j]=1;
else if(i==0&&j==1) dp[i][j]=1;
else if(i==1&&j==0) dp[i][j]=1;
else
{
dp[i][j]=dp[i-1][j-1]+1;
}
}
else dp[i][j]=0;
ans=max(ans,dp[i][j]);
}
}
//cout<<ans<<endl;
cout<<s1.length()+s2.length()-2*ans<<endl;
}
return 0;
}
D - Epic Transformation
思路
我看了好多大佬都是直接把每个点的次数存进来,然后就用优先队列每次拿出两个数来减一,最后输出队列中的值。
还有一些人是发现了一些性质,如果一个点的次数比其他所有点的次数都大的话,那就用这个最大次数减去其他的就是结果,如果小于的话,就判断n%2的结果,但是我到现在也不会证明。。
代码
#include <bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define me memset
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
int main()
{
int t;
cin>>t;
while(t--)
{
map<int,int>mp;
int n;
cin>>n;
int maxx=0;
for(int i=1 ; i<=n ; i++)
{
int x;
cin>>x;
mp[x]++;
maxx=max(maxx,mp[x]);
}
if(maxx>=n-maxx)
{
cout<<maxx*2-n<<endl;
}
else
{
if(n%2==0) cout<<"0"<<endl;
else cout<<"1"<<endl;
}
}
return 0;
}
E - Restoring the Permutation
思路
我感觉E题比D题简单,这个题只需要找到一个能支持删除和查找功能的数据结构就行,我用的是set,剩下的事情就是模拟就行了。
代码
#include <bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define me memset
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
int a[N];
int main()
{
int t;
cin>>t;
while(t--)
{
set<int>s1,s2;
int n;
cin>>n;
for(int i=1 ; i<=n ; i++) s1.insert(i);
for(int i=1 ; i<=n ; i++) s2.insert(i);
for(int i=1 ; i<=n ; i++) cin>>a[i];
for(int i=1 ; i<=n ; i++)
{
int x=a[i];
int j=i+1;
while(x==a[j])
{
a[j]=0;
j++;
}
i=j-1;
}
// for(int i=1 ; i<=n ; i++) cout<<a[i]<<" ";
// cout<<endl;
for(int i=1 ; i<=n ; i++)
{
if(a[i]!=0)
{
cout<<a[i]<<" ";
s2.erase(a[i]);
}
if(a[i]==0)
{
auto it=s2.begin();
cout<<*it<<" ";
s2.erase(*it);
}
}
cout<<endl;
for(int i=1 ; i<=n ; i++)
{
// cout<<i<<" "<<a[i]<<endl;
if(a[i]!=0)
{
cout<<a[i]<<" ";
}
if(a[i-1]!=0&&a[i]!=0)
{
if(s1.find(a[i-1])!=s1.end()) s1.erase(a[i-1]);
}
if(a[i]==0)
{
auto it=s1.find(a[i-1]);
// cout<<"a["<<i-1<<"]="<<a[i-1]<<endl;
it--;
cout<<*it<<" ";
a[i]=*it;
s1.erase(a[i-1]);
}
}
cout<<endl;
}
return 0;
}
总结
昨天晚上被A和C题搞的有点心态蹦了,A想了好久,写出来的时候都已经过了6000人了,C题居然一直最长公共字串的DP写错了,自己的基础太不牢固了。