0
点赞
收藏
分享

微信扫一扫

Codeforces Round #719 (Div. 3) 题解

A.Do Not Be Distracted!

  • 解题思路
    利用Codeforces Round #719 (Div. 3) 题解_i++容器记录之前出现过的字母,我们只需要遍历字符串判断当前的字符有没有在之前出现过(注意是不连续的出现)。
  • AC代码
/**
*@filename:A_Do_Not_Be_Distracted_
*@author: pursuit

*@created: 2021-05-05 22:35
**/
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxn = 100000 + 5;
const int mod = 1e9+7;

int t,n;
string s;
map<char,int> p;
void solve(){
p.clear();
char pre=s[0];
p[pre]++;
bool flag=false;
for(int i=1;i<n;i++){
if(s[i]!=pre){
if(p.find(s[i])!=p.end()){
flag=true;
break;
}
else{
pre=s[i];
p[s[i]]++;
}
}
}
if(!flag){
cout<<"YES"<<endl;
}
else{
cout<<"NO"<<endl;
}
}
int main(){
cin>>t;
while(t--){
cin>>n;
cin>>s;
solve();
}
return 0;
}

B.Ordinary Numbers

  • 解题思路
    此题需要我们知道1~n以内的所有普通数,即位数上的数字都相等,那么这种数有什么规律呢?Codeforces Round #719 (Div. 3) 题解_#include_02Codeforces Round #719 (Div. 3) 题解_#include_03Codeforces Round #719 (Div. 3) 题解_i++_04。我们发现,实际上只需要起始从Codeforces Round #719 (Div. 3) 题解_算法_05构成的相等数开始,再每次加上这个数即可。需要注意的就是进位。
  • AC代码
/**
*@filename:B_Ordinary_Numbers
*@author: pursuit

*@created: 2021-05-05 22:39
**/
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxn = 100000 + 5;
const int mod = 1e9+7;

int t,n;
bool check(int x){
string temp=to_string(x);
for(int i=0;i<temp.size()-1;i++){
if(temp[i]!=temp[i+1])return false;
}
return true;
}
void solve(){
int ans=0;
int k=1,temp=1;
for(int i=temp;i<=n;i+=temp){
if(check(i))ans++;
else{
//不行,说明已经进位,我们需要让temp变为当前长度的1。
temp=temp*10+1;
i=0;
}
}
cout<<ans<<endl;
}
int main(){
cin>>t;
while(t--){
cin>>n;
solve();
}
return 0;
}

C. Not Adjacent Matrix

  • 解题思路
    构造问题,我们是要让相邻单元格的差值不为Codeforces Round #719 (Div. 3) 题解_i++_06,所以我们自然能想到用奇数和奇数相邻,偶数和偶数相邻,所以我们可以先从小到大填充所有的奇数,填完奇数之后再从小到大填充完所有的偶数。这种做法除了Codeforces Round #719 (Div. 3) 题解_算法_07不满足情况,其他的均可满足。因为除Codeforces Round #719 (Div. 3) 题解_算法_07之外奇数和偶数相邻的那部分单元格差值不为Codeforces Round #719 (Div. 3) 题解_i++_06
  • AC代码
/**
*@filename:C_Not_Adjacent_Matrix
*@author: pursuit

*@created: 2021-05-05 22:49
**/
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxn = 100 + 5;
const int mod = 1e9+7;

int t,n;
int a[maxn][maxn];
void solve(){
if(n==2)cout<<-1<<endl;
else{
int odd=1,even=2;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(odd>n*n){
a[i][j]=even;
even+=2;
}
else{
a[i][j]=odd;
odd+=2;
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cout<<a[i][j]<<" ";
}
cout<<endl;
}
}
}
int main(){
cin>>t;
while(t--){
cin>>n;
solve();
}
return 0;
}

D. Same Differences

  • 解题思路
    这道题其实特别简单,我们需要将给定的公式变形,即Codeforces Round #719 (Div. 3) 题解_c代码_10,变形得到Codeforces Round #719 (Div. 3) 题解_codeforces_11。这样题目实际上就解决了。利用Codeforces Round #719 (Div. 3) 题解_i++容器记录Codeforces Round #719 (Div. 3) 题解_codeforces_13出现的次数,遍历数组的时候累加之前出现的Codeforces Round #719 (Div. 3) 题解_codeforces_13的次数即可。需要注意的就是统计用long long类型,会爆int。
  • AC代码
/**
*@filename:D_Same_Differences
*@author: pursuit

*@created: 2021-05-05 22:57
**/
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxn = 200000 + 5;
const int mod = 1e9+7;

int t,n,a[maxn];
map<int,int> p;
void solve(){
ll ans=0;
//aj-j=ai-i;
for(int i=1;i<=n;i++){
ans+=p[a[i]-i];
p[a[i]-i]++;
}
cout<<ans<<endl;
}
int main(){
cin>>t;
while(t--){
cin>>n;
p.clear();
for(int i=1;i<=n;i++)cin>>a[i];
solve();
}
return 0;
}

E. Arranging The Sheep

  • 解题思路
    根据贪心原则,我们总是想往中间靠,那么我们则需要找到最中间的Codeforces Round #719 (Div. 3) 题解_算法_15即可,所以我们可以将这些Codeforces Round #719 (Div. 3) 题解_算法_15字符的下标存储起来,需要处理的一个细节就是,我们需要将连续的Codeforces Round #719 (Div. 3) 题解_算法_15看成是一个点,因为它们转移的消耗是一样的。处理完之后,开始判断选取哪个中点,取最小值即可。
  • AC代码
/**
*@filename:E_Arranging_The_Sheep
*@author: pursuit

*@created: 2021-05-05 23:16
**/
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxn = 1000000 + 5;
const int mod = 1e9+7;

int t,n;
string s;
void solve(){
vector<int> pos;
//我们可以认为连续的就是同一个点,这样方便处理。
int idx=1;
for(int i=0;i<n;i++){
if(s[i]=='*')pos.push_back(idx);
else idx++;
}
if(pos.empty()){
//说明为空。
cout<<0<<endl;
return;
}
//选择中间位置进行处理。
int idx1=pos.size()/2,idx2=(pos.size()-1)/2;
ll cnt1=0,cnt2=0;
/* for(int i=0;i<pos.size();i++){
cout<<pos[i]<<" ";
} */
/* cout<<endl; */
for(int i=0;i<pos.size();i++){
cnt1+=abs(pos[idx1]-pos[i]);
cnt2+=abs(pos[idx2]-pos[i]);
/* cout<<cnt1<<" "<<cnt2<<endl; */
}
cout<<min(cnt1,cnt2)<<endl;
}
int main(){
cin>>t;
while(t--){
cin>>n>>s;
solve();
}
return 0;
}

F1. Guess the K-th Zero (Easy version)

  • 题目大意
    给定一个Codeforces Round #719 (Div. 3) 题解_算法_18数组的长度,我们需要利用不超过Codeforces Round #719 (Div. 3) 题解_codeforces_19次的查询来找到第Codeforces Round #719 (Div. 3) 题解_i++_20Codeforces Round #719 (Div. 3) 题解_i++_21的位置。在简单版本中,我们只需要找一个Codeforces Round #719 (Div. 3) 题解_i++_20
  • 解题思路
    对于这种问题,我们应该要想到二分查找,这样我们才能保证在不超过Codeforces Round #719 (Div. 3) 题解_codeforces_19次的查询来找到第Codeforces Round #719 (Div. 3) 题解_i++_20Codeforces Round #719 (Div. 3) 题解_i++_21的位置,因为Codeforces Round #719 (Div. 3) 题解_算法_26。那么二分的话我们需要维护一个可行区间Codeforces Round #719 (Div. 3) 题解_codeforces_27,每次查询Codeforces Round #719 (Div. 3) 题解_codeforces_28,而返回的结果Codeforces Round #719 (Div. 3) 题解_i++_29是该区间中Codeforces Round #719 (Div. 3) 题解_算法_05的个数,那么自然该区间中Codeforces Round #719 (Div. 3) 题解_i++_21的个数为Codeforces Round #719 (Div. 3) 题解_#include_32,我们用这个与Codeforces Round #719 (Div. 3) 题解_i++_20比较,判断我们查询的Codeforces Round #719 (Div. 3) 题解_i++_20在哪个区间即可,需要注意的是,如果是在右边,那么我们需要更新Codeforces Round #719 (Div. 3) 题解_i++_20,因为我们在意的是相对位置,而左区间已经有Codeforces Round #719 (Div. 3) 题解_#include_32Codeforces Round #719 (Div. 3) 题解_i++_21了,那么终止的时候也就是找到了第Codeforces Round #719 (Div. 3) 题解_i++_20Codeforces Round #719 (Div. 3) 题解_i++_21的位置,即Codeforces Round #719 (Div. 3) 题解_#include_40
  • AC代码
/**
*@filename:F1_Guess_the_K_th_Zero_Easy_version_
*@author: pursuit

*@created: 2021-05-06 00:06
**/
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxn = 100000 + 5;
const int mod = 1e9+7;

int t,n,k;
//二分查找。
void solve(){
int T=20;//查找次数最多20次。
int l=1,r=n;
while(T--){
int mid=(l+r)>>1;//我们每次二分查询即可得到所在区间。
cout<<"?"<<" "<<l<<" "<<mid<<endl;
cout.flush();
int res;
cin>>res;//这个即返回的是[l,mid]这段区间的1的数量,那么0的数量自然易得。
int cnt=mid-l+1-res;
if(cnt<k){
//说明第k个0在右边。
k-=cnt;
l=mid+1;
}
else{
//说明第k个0在左边。
r=mid;
}
if(l==r){
cout<<"! "<<l<<endl;
break;
}
}
}
int main(){
cin>>n>>t;
while(t--){
cin>>k;
solve();
}
return 0;
}

F2. Guess the K-th Zero (Hard version)

  • 解题思路
    目前还不会,待补。

G. To Go Or Not To Go?

  • 解题思路
    我们知道若Codeforces Round #719 (Div. 3) 题解_i++_41Codeforces Round #719 (Div. 3) 题解_算法_42,则说明不准通行,否则其他的都可以正常移动,每次移动的消耗为Codeforces Round #719 (Div. 3) 题解_c代码_43。特殊的是若该点权值大于Codeforces Round #719 (Div. 3) 题解_i++_44,说明可以使用传送器到有传送器的地方,消耗为Codeforces Round #719 (Div. 3) 题解_i++_45。由于可以任意传送,所以其实使用传送器只会使用一次。那么我们就可以先计算出不使用传送器从Codeforces Round #719 (Div. 3) 题解_i++_46出发和从Codeforces Round #719 (Div. 3) 题解_算法_47出发到达各点的最短路径,得到了这些之后,我们就可以枚举使用的传送门(记住,这里的传送门有两处,一处是从起点到达的Codeforces Round #719 (Div. 3) 题解_c代码_48,一处是从Codeforces Round #719 (Div. 3) 题解_c代码_48传送到达的Codeforces Round #719 (Div. 3) 题解_#include_50)取最优了,即维护Codeforces Round #719 (Div. 3) 题解_算法_51Codeforces Round #719 (Div. 3) 题解_i++_52的最小值,然后再与不使用传送门直接到达Codeforces Round #719 (Div. 3) 题解_算法_47Codeforces Round #719 (Div. 3) 题解_算法_54取最小值即可。
  • AC代码
/**
*@filename:G_To_Go_Or_Not_To_Go_
*@author: pursuit

*@created: 2021-05-06 21:45
**/
#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
const int maxn = 2000 + 5;
const int mod = 1e9+7;
const ll inf = 0x3f3f3f3f3f3f3f;

int n,m,w;
ll dist1[maxn][maxn],dist2[maxn][maxn];//dist1[i][j]表示(1,1)到(i,j)的最短路径,dist2[i][j]表示(n,m)到(i,j)的最短路径。
int g[maxn][maxn];//图。
int go[4][2]={0,1,1,0,0,-1,-1,0};//行走路径。
void bfs(pii st,ll dist[maxn][maxn]){
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
dist[i][j]=inf;//初始化。
}
}
queue<pii> q;
dist[st.x][st.y]=0;
pii head,temp;
q.push(st);
while(!q.empty()){
head = q.front();
q.pop();
for(int i=0;i<4;i++){
temp.x=head.x+go[i][0],temp.y=head.y+go[i][1];
if(temp.x>=1&&temp.x<=n&&temp.y>=1&&temp.y<=m&&g[temp.x][temp.y]!=-1&&dist[temp.x][temp.y]>dist[head.x][head.y]+w){
dist[temp.x][temp.y]=dist[head.x][head.y]+w;
q.push(temp);
}
}
}
}
void solve(){
bfs({1,1},dist1);
bfs({n,m},dist2);
ll minn1=inf,minn2=inf;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
//穿插使用传送门,优化最小值。
if(g[i][j]<=0)continue;
minn1=min(minn1,dist1[i][j]+g[i][j]);
minn2=min(minn2,dist2[i][j]+g[i][j]);
//cout<<minn1<<" "<<minn2<<endl;
}
}
ll ans=min(minn1+minn2,dist1[n][m]);
if(ans>=inf)ans=-1;
printf("%lld\n",ans);//注意是lld
}
int main(){
scanf("%d%d%d",&n,&m,&w);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&g[i][j]);
}
}
solve();
return 0;
}


举报

相关推荐

0 条评论