比赛链接
Dashboard - Educational Codeforces Round 111 (Rated for Div. 2) - Codeforces
A - Find The Array
题意
给出一个有n个元素的数组,如果元素不为1的话,那么就询问a[i]-1和a[i]-2是否在数组里面。求给出总数和为s,元素个数最少的是多少。
思路
最优的情况就是1,3,5,...这样可以“消耗”更多的s,进而能保证元素最少,那么可以看出1+3+5=,也就是这样奇数相加是平方和,那么我们就对s进行判断,如果是完全平方数那么就输出它的根号,如果不是那么输出根号加1.
代码
#include<stack>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<cstring>
#include<deque>
#include<vector>
#include<iostream>
#include<map>
#include<set>
#include<iomanip>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
using namespace std;
ll GCD(ll a,ll b){while(b^=a^=b^=a%=b);return a;}
const int inf=0x3f3f3f3f;
int n,s,x;
signed main()
{
#ifndef ONLINE_JUDGE
freopen("IO\\in.txt","r",stdin);
freopen("IO\\out.txt","w",stdout);
#endif
IOS
cin>>n;
for (int i=1;i<=n;i++)
{
cin>>s;
int x=sqrt(s);
if (x*x==s) cout<<x<<endl;
else cout<<x+1<<endl;
}
return 0;
}
B - Maximum Cost Deletion
题意
给出一个01序列,我们可以让其中连续的(包括1个)0或者1消除,得到一个新的字符串,可以这样一直下去直到没有。题目除了给出长度和字符串外,还给出了a和b两个变量,每一次操作得分为,
是这个操作中选取的长度。求最大得分。
思路
我们对进行观察,发现无论截取多少次,对于
这一项是永远不变的,主要是看b,我们取的或多或少对b有影响很大。如下图:
所以我们看b的范围:
1)b>0。那么我们想要b越来越多,那么我们就一个一个取,这样得分最大。
2)b<0。那么我们就希望次数越少越好,我们每次选择连续的,扫一遍得到有多少个01段,如果得出来有cnt块,那么不难证明只需要(cnt/2+1)次可以全部消除。
3)b=0。随便归为哪一类都行。
代码
#include<stack>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<cstring>
#include<deque>
#include<vector>
#include<iostream>
#include<map>
#include<set>
#include<iomanip>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
using namespace std;
ll GCD(ll a,ll b){while(b^=a^=b^=a%=b);return a;}
const int inf=0x3f3f3f3f;
const int N = 110;
int sum,num[N];
string st;
int n,a,b,cnt,T;
char tmp;
signed main()
{
#ifndef ONLINE_JUDGE
freopen("IO\\in.txt","r",stdin);
freopen("IO\\out.txt","w",stdout);
#endif
IOS
cin>>T;
while (T--)
{
cin>>n>>a>>b>>st;
tmp=st[0];sum=1;cnt=0;
for (int i=1;i<n;i++)
{
if (st[i]!=tmp)
{
if (tmp=='0') tmp='1';
else tmp='0';
num[++cnt]=sum;
sum=1;
}
else
{
sum++;
}
}
num[++cnt]=sum;
//for (int i=1;i<=cnt;i++) cout<<num[i]<<" ";
//cout<<endl;
if (b<0) cout<<b*(cnt/2+1)+a*n<<endl;
else cout<<(a+b)*n<<endl;
}
return 0;
}
C - Manhattan Subarrays
题意
如果一个区间内有三个点p,q,r能满足,
表示的是i和j之间的曼哈顿距离,那么我们就说这个是“坏的”,如果区间长度为1或2,那么这个是“好的”。求长度为n的给出具体数字的数组,有多少个“好的”区间。
思路
这个题昨天把我搞自闭了...不知道是属于哪个数据结构,想半天想放弃去吃外卖,但是又不想放弃,去往LIS上想...哎
郎队在群里讲了一下长度为5的绝对不可能,我发现好有道理!!但是自己那时候没打算打了,今天来补。
经过题目稍微画图分析,发现这三个点满足非严格递增或递减就不行,所以我们只需要将长度为1,2的加上,长度为3,4取判断是否非严格递增即可。
代码
#include<stack>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<cstring>
#include<deque>
#include<vector>
#include<iostream>
#include<map>
#include<set>
#include<iomanip>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
using namespace std;
ll GCD(ll a,ll b){while(b^=a^=b^=a%=b);return a;}
const int inf=0x3f3f3f3f;
const int N = 200007;
int T,a[N],ans,n;
inline bool check(int a,int b,int c)
{
if (a<=b&&b<=c) return false;
if (a>=b&&b>=c) return false;
return true;
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("IO\\in.txt","r",stdin);
freopen("IO\\out.txt","w",stdout);
#endif
IOS
cin>>T;
while (T--)
{
cin>>n;
for (int i=1;i<=n;i++) cin>>a[i];
ans=n*2-1;
for (int i=1;i<=n-3+1;i++)
{
if (check(a[i],a[i+1],a[i+2])) ans++;
if (i<=n-4+1)
{
int boo=true;
if (!check(a[i],a[i+1],a[i+2])) boo=false;
if (!check(a[i],a[i+1],a[i+3])) boo=false;
if (!check(a[i],a[i+2],a[i+3])) boo=false;
if (!check(a[i+1],a[i+2],a[i+3])) boo=false;
if (boo) ans++;
}
}
cout<<ans<<endl;
}
return 0;
}