A Tokitsukaze and Bracelet
题目描述
代码
#include<bits/stdc++.h>
using namespace std;
void solve(){
int ans=0;
int a,b,c;cin>>a>>b>>c;
if(a==150)ans+=1;
else if(a==200)ans+=2;
if(b>=34&&b<=40)ans+=1;
else if(b==45)ans+=2;
if(c>=34&&c<=40)ans+=1;
else if(c==45)ans+=2;
cout<<ans<<'\n';
}
int main(){
int t;cin>>t;
while(t--)solve();
return 0;
}
B Tokitsukaze and Cats
分析
首先需要注意的是在边界的时候也是需要网的,不能靠墙壁防住,然后每一个格子需要4个网,然后每两个格子相邻的话,相邻的格子就只需要一个网,对于当前格子,我们枚举一下当前格子的四个方向,看看有没有在我们map中,在的话然后减一下,得出最后的答案
代码
#include<bits/stdc++.h>
using namespace std;
const int N=100010;
typedef pair<int,int>PII;
struct node{
int x,y,val;
}a[N];
int main()
{
ios::sync_with_stdio(0),cin.tie(0);
int n,m,k;cin>>n>>m>>k;
map<PII,int>mp;
for(int i=1;i<=k;i++){
int x,y;cin>>x>>y;
a[i].x=x,a[i].y=y;
mp[{x,y}]=1;
}
int ans=k*4;
for(int i=1;i<=k;i++){
mp[{a[i].x,a[i].y}]=0;//标记已经走过了
if(mp[{a[i].x+1,a[i].y}])
ans--;
if(mp[{a[i].x-1,a[i].y}])
ans--;
if(mp[{a[i].x,a[i].y+1}])
ans--;
if(mp[{a[i].x,a[i].y-1}])
ans--;
}
cout<<ans<<'\n';
return 0;
}
E Tokitsukaze and Eliminate (easy)
分析
首先看题目的col限制,可以得到这个序列一共就只有三种情况,全是1,全是2,部分1部分2,对于前两种我们特判一下,直接返回他有几个数就是答案。然后对于第三种,我们从后往前枚举,枚举到当前12两个数字中最后出现的,比如2112,最后第一次枚举的时候最后出现的就是第三个数1,第二次枚举的就是第一个数字2。我们可以用一个set来实现,当然12的数量也不一定是均分的,所以必然会存在一个数字落单的情况,比如111212,前两个1是落单的,需要两次操作,于是我们只需要最后判断一下,一个没有了一个还有,加上有的那个的大小就可以了。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int a[N];
void solve(){
int n;cin>>n;
if(n==1){
cout<<1<<'\n';return;
}
map<int,int>mp;
for(int i=1;i<=n;i++){
cin>>a[i];
mp[a[i]]++;
}
if(mp[1]&&!mp[2]){
cout<<mp[1]<<'\n';return;
}
if(!mp[1]&&mp[2]){
cout<<mp[2]<<'\n';return;
}
set<int>s;
int ans=0;
for(int i=n;i>=1;i--){
s.insert(a[i]);
mp[a[i]]--;
if(s.size()==2){
s.clear();
ans++;
}
if(mp[2]>0&&!mp[1]){
ans+=mp[2];
break;//记得break
}
if(mp[1]>0&&!mp[2]){
ans+=mp[1];
break;
}
}
cout<<ans<<'\n';
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0);
int t;cin>>t;
while(t--)solve();
return 0;
}
F Tokitsukaze and Eliminate (hard)
分析
与刚刚的情况不同,刚刚是2没有了就只剩下1了,但是现在范围变得更大了,没有5了可能还有4,还有3之类的,所以我们这里需要开一个cnt[i]数组来记录下,到当前元素为止,有多少个不同的元素,然后从后往前枚举,跟刚才的情况差不多。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int a[N],cnt[N];//cnt来记录下放入当前数字之后去重后总共有多少个数
void solve(){
//memset(cnt,0,sizeof cnt);
int n;cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
set<int>s1,s2;
for(int i=1;i<=n;i++){
s1.insert(a[i]);
cnt[i]=s1.size();//如果cnt[i]==cnt[i+1] 说明当前的数已经在前面出现过,最后cnt[n]就是总共有多少个不同的数字
}
int ans=0;
for(int i=n;i>=1;i--){
s2.insert(a[i]);
if(s2.size()==cnt[n]){//当前已经到了最后出现的,删除这个数后面一定最有
n-=(n-i+1);
s2.clear();
ans++;
}
}
cout<<ans<<'\n';
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0);
int t;cin>>t;
while(t--)solve();
return 0;
}
I Tokitsukaze and Short Path (plus)
添加图片注释,不超过 140 字(可选)
分析
首先看到最短路,肯定首先就想到了dijkstra,再看题目,任意两点之间,好,floyd, n三方,再看范围2e5,还有个t,直接tle飞啦。所以我们重新考虑一下,这个边的权值跟一般的不一样啊,有绝对值,我们考虑去一下绝对值,当 时候,权值是 ,当 时候,权值是 ,这样一想,这不就是哪个点大,权值就是那个的两倍吗。然后再看题目要求的是任意两点之间的最短路之和,然后根据题目路径又是由点决定的,所以就转化到了点权求和。假设n=4,答案就是要求1->1,1->2,1->3,1->4,2->2,2->3......,由于是双向边,1->2和2->1是一样的,然后再去重之后,答案就是求1->2,1->3,1->4,2->3,2->4,3->4的两倍。然后对于两点之间的距离又是两点之间的最大值的两倍。假如最大的是n=4,这几个点权值依次增大,那么上述对应的边权值应该为2,3,4,3,4,4(编号),我们发现最大的被计算了3次,然后依次减小......,即计算方式应该为 ,然后最后乘上个2。
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5+10;
int a[N];
void solve(){
int n;cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
int ans=0;
sort(a+1,a+1+n);
for(int i=1;i<=n;i++)
ans+=(a[i]*(i-1)*2)*2;
cout<<ans<<'\n';
}
signed main()
{
ios::sync_with_stdio(0),cin.tie(0);
int t;cin>>t;
while(t--)solve();
return 0;
}
J Tokitsukaze and Short Path (minus)
分析
首先一样的我们先去一下绝对值符号,当时候,权值是,当 时候,权值是 ,那不是与刚刚相反了吗,所以一样排序就可以了?
与刚刚不同是现在是选取小的那一个,我们看第二张图的样例解释,发现1->3的最短路是1->2,2->3,并不是1->3,所以直接跟上面一样反过来是不对的。当然也有可能是1->3更短,于是我们对两种情况取最小即可,第一种距离为1->2+2->3+(1->3==(1->2+2->3)),于是最后答案为 ,因为可能所有的最短路都是由最小边权构成的。
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5+10;
int a[N];
void solve(){
int n;cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
int ans=0;
sort(a+1,a+1+n);
for(int i=1;i<n;i++)
ans+=min(a[1]*4,a[i]*2)*2*(n-i);
cout<<ans<<'\n';
}
signed main()
{
ios::sync_with_stdio(0),cin.tie(0);
int t;cin>>t;
while(t--)solve();
return 0;
}