0
点赞
收藏
分享

微信扫一扫

Ozon Tech Challenge 2020 (Div.1 + Div.2, Rated, T-shirts + prizes!)

余寿 2022-09-26 阅读 30

地址:​​http://codeforces.com/contest/1305​​

Ozon Tech Challenge 2020 (Div.1 + Div.2, Rated, T-shirts + prizes!)_数据

  

Ozon Tech Challenge 2020 (Div.1 + Div.2, Rated, T-shirts + prizes!)_i++_02

题意:A题写这么长,实际上意思很简单,给出两组长度相等的数,让你给出排列顺序,保证每一列上下加起来不同。

    解析:很水了,小+大=大+小,根据这个,只要上下均按从小到大的顺序排列就可以了。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long ll;
int a[1005],b[1005];
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
for(int i=0;i<n;i++)
cin>>b[i];
sort(a,a+n);sort(b,b+n);
for(int i=0;i<n-1;i++)
cout<<a[i]<<" ";
cout<<a[n-1]<<endl;
for(int i=0;i<n-1;i++)
cout<<b[i]<<" ";
cout<<b[n-1]<<endl;
}
}

 

Ozon Tech Challenge 2020 (Div.1 + Div.2, Rated, T-shirts + prizes!)_数据_03

Ozon Tech Challenge 2020 (Div.1 + Div.2, Rated, T-shirts + prizes!)_#include_04

 

题意:题意我是理解了有一会儿,特别是这个Output最后关于k的说明,烟雾弹一样搞得人迷糊。给出一个只含(,)的字符串,让你删除最少的字符来使它变成一个标准的(题中的simple string):左边一半全是(,右边一半全是)。输出目标字符串,即删除后得到的,但是下标还是原字符串的。

    解析:经过分析,删除是任意删的,完全没限制,所以说这个k要么是0,要么是1。先特判一下 ( 和 ) 的数目,==0肯定不行,直接输出0。数据很小,直接暴力:从左边开始,i处找到一个(,再从尾开始,j>i处找一个还没用过的)跟它配对,用vis标记用没用过。即每次配一个()。完毕以后,没被vis标过的,即需要删除的地方,当然不需要输出它,输出被vis标记过的。

      第一发WA了,经过检查发现,对于一个已经完美的string,直接输出全坐标就可以,出错的原因是代码写着写着忘了题意,嘿嘿。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e3+10;
char s[maxn];
int vis[maxn];
int main()
{
cin>>s;
int l1=0,l2=0;
int len=strlen(s);
for(int i=0;i<len;i++)
{
if(s[i]==')')
l2++;
else
l1++;
}
if(l2==0||l1==0)
{
cout<<"0"<<endl;return 0;
}


for(int i=0;i<len;i++)
{
if(s[i]=='('&&!vis[i])
{
int ok=0;
for(int j=len-1;j>i;j--)
{
if(s[j]==')'&&!vis[j])
{
vis[j]=1;
ok=1;
break;
}
}
if(ok)
vis[i]=1;
}
}
int k=0,cnt=0;
for(int i=0;i<len;i++)
{
if(vis[i])
{
k=1;cnt++;
}
}
if(!k)
cout<<"0"<<endl;
else
{
cout<<"1"<<endl;
cout<<cnt<<endl;
int cnt2=0;
for(int i=0;i<len;i++)
{
if(vis[i]&&cnt2<cnt)
{
cnt2++;
cout<<i+1<<" ";
}
else if(vis[i]&&cnt2==cnt)
{
cout<<i+1<<endl;
}
}
}
}

Ozon Tech Challenge 2020 (Div.1 + Div.2, Rated, T-shirts + prizes!)_#include_05

Ozon Tech Challenge 2020 (Div.1 + Div.2, Rated, T-shirts + prizes!)_#include_06

题意:就上图中那么乘的,不解释了。

    解析:看数据,暴力肯定不可行。我开始以为是数论,放弃了。赛后一看解析,才是恍然大悟。

      一:n<=m。数据小于<1000,直接暴力

      二:n>m。

        首先明白这一点:如果两个数,a,b除以m的余数相同,那么它们的差是m的倍数!!!

        根据鸽巢原理,%m,那么存在余数m种,而n>m,那么必然存在两个数%m相同,那么它们的差,就是m的倍数。那么存在|a[i]-a[j]|%m==0,最终结果就是0

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn = 2e5+10;
ll a[maxn];
int main()
{
int n, m ;
cin>>n>>m;
ll sum=1;
for(int i=0;i<n;i++)
cin>>a[i];
if(n<=m)
{
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
ll mid=fabs(a[i]-a[j]);
sum=sum*mid%m;
}
}
cout<<sum<<endl;
}
else
cout<<'0'<<endl;
}

 



举报

相关推荐

0 条评论