您的位置:首页 > 其它

Educational Codeforces Round 35 (Rated for Div. 2)

2018-01-03 21:05 741 查看
传送门:http://codeforces.com/contest/911

A. Nearest Minimums

题意:和题目的名字一样,求最小的数的最近距离(保证最小的数字有2个以上)

思路:直接找最小值。然后记录没两个相邻的最小值的距离,求最小值。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<map>
#include<cstdlib>
using namespace std;
typedef double db;
typedef long long ll;
int a[110000];
int b[110000];
int main ()
{
//yyy_3y
// freopen("1.in","r",stdin);
int n; scanf("%d",&n);
int minn=1e9;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
minn=min(a[i],minn);
}
int dis=1e9;
int cnt=0;
for(int i=1;i<=n;i++){
if(a[i]==minn) b[cnt++]=i;
}
for(int i=1;i<cnt;i++){
dis=min(dis,b[i]-b[i-1]);
}
printf("%d\n",dis);
}


#include<bits/stdc++.h>
using namespace std;
typedef double db;
typedef long long ll;
int a[110000];
int b[110000];
int main ()
{
//yyy_3y
// freopen("1.in","r",stdin);
int n; scanf("%d",&n);

for(int i=1;i<=n;i++) scanf("%d",&a[i]);
int mi=a[1];
for(int i=1;i<=n;i++) mi=min(a[i],mi);
vector<int> E;
for(int i=1;i<=n;i++){
if(mi==a[i]) E.push_back(i);
}
int ans=n;
for(int i=0;i+1<(int)E.size();i++){
ans=min(ans,E[i+1]-E[i]);
}
printf("%d\n",ans);
}


B. Two Cakes

题意:给盘子个数n,两份蛋糕块数a和b,需要在每个盘子最多放几块蛋糕保证所有蛋糕块都装下。

思路:枚举即可。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<map>
#include<cstdlib>
using namespace std;
typedef double db;
typedef long long ll;
int main ()
{
//yyy_3y
// freopen("1.in","r",stdin);
int a,b,c; scanf("%d%d%d",&a,&b,&c);
if(b+c<a) printf("0\n");
else {
int maxx=-1;
for(int i=1;i<a;i++){
int d=a-i;
int lo=b/i;
int loo=c/d;
int mm=min(lo,loo);
if(mm>maxx) maxx=mm;
}
printf("%d\n",maxx);
}
return 0;
}


C. Three Garlands

题意:给你三个灯,分别以k1秒一次,k2秒一次和k3秒一次的频率闪烁着。

你可以自定义三个灯开启的时间,问是否有一种方案,保证每一秒的灯至少有一盏是亮的。

思路:特判就行。有1个1,2个2,3个3或者一个1和4个2 四种情况是YES。其他都是NO。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<map>
#include<cstdlib>
using namespace std;
typedef double db;
typedef long long ll;
int a[1600];
int main ()
{
//yyy_3y
// freopen("1.in","r",stdin);
int k1,k2,k3; cin >>k1>>k2>>k3;
a[k1]++;a[k2]++;a[k3]++;
int cnt2=a[2],cnt1=a[1],cnt3=a[3],cnt4=a[4];
if(cnt1>=1||cnt2>=2||cnt3>=3) cout << "YES" <<endl;
else if (cnt2==1 && cnt4==2) cout << "YES" <<endl;
else cout << "NO" << endl;
}


D. Inversion Counting

题意:给你一个数列,翻转其中一个区间,问每次翻转过后逆序对个数的奇偶性。

思路:先树状数组求逆序对的个数,然后考虑每次反转的贡献度。

对于区间L,R的转化,可以变成 L和R转化,L-1,R-1……

一共就是(R-L+1)/2次。

那么L,R的交换以后,对于L,改变的逆序对数为区间[L,R]大于L的数与小于R的数之差。对于R,同理。

那L和R造成的影响就是2*(R-L)。 一定是偶数,加上R,L这一对,一定是奇数。

只需要看(R-L+1)/2 是奇数还是偶数就行。

如果数偶数不变,奇数的(如果一开始是奇数变偶数,否则边奇数)。

//#include<bits/stdc++.h>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 501000
#define ll long long
int a
, s
, sum
;
int n;
void update(int x, int y)
{
while (x <= n){
sum[x] += y;
x += x & -x;
}
}
ll read(ll x)
{
ll ans = 0;
while (x){
ans += sum[x];
x -= x & -x;
}
return ans;
}
int main ()
{
while (scanf("%d",&n)!=EOF && n){
memset(sum,0,sizeof(sum));
memset(s,0,sizeof(s));
for (int i = 1; i <= n; i++)
scanf("%d",&a[i]), s[i] = a[i];
sort(s+1,s+n+1);
ll Ans = 0;
int k = unique(s+1, s+n+1) - s;
for (int i = 1; i <= n; ++i) a[i] = lower_bound(s+1,s+n+1,a[i]) - s ;
for (int i = 1; i <= n; ++i){
ll temp = read(a[i]);
Ans += i -temp - 1;
update(a[i],1);
}
//   printf("%lld\n",Ans);
int flag;
if (Ans%2==0) flag=1;
else flag=0;
int m; scanf("%d",&m);
for(int i=1;i<=m;i++){
int l,r; scanf("%d%d",&l,&r);
l=r-l+1;
l/=2;
if(l%2) flag=1-flag;
if(flag) printf("even\n");
else printf("odd\n");
}
}
return 0;
}


E. Stack Sorting

题意:一个长度为n的序列a,一种空栈s,一个空序列b。

你可以执行两个操作:

①把a的第一个数放到栈s。

②把s中的top放入b中。

如果你能通过这两个操作把 a中的数最后都放入 b 中,且 b 是升序的,那就可说a是 stack-sortable 。

现在给你前k的数,问有没有stack-sortable的数,如果有输出字典序最大,否则输出-1。

思路:a中如果出现 ” 中 、大、小 ” 这样顺序的就是不可能。

把前 k 个数从小到大排序后,变为 a1, a2, …… ak 。 后面 n-k 个数,先输出 a1->1,再是 a2 -> a1, 再是 a3->a2, a4->a3 ……..,ak -> a(k-1), n -> ak 。

tips:vector的end() 函数返回一个指向当前vector末尾元素的下一位置的迭代器.要访问末尾元素,需要先将此迭代器减1。

vector的back() 函数返回当前vector最末一个元素的引用。

vector.pop_back();可以高效地移除vector中的最后一个元素.

#include<bits/stdc++.h>
using namespace std;
const int MAXN=200005;
int loc[MAXN];
int a[MAXN];
int main ()
{
int n,k; scanf("%d%d",&n,&k);
for(int i=1;i<=k;i++) scanf("%d",&a[i]),loc[a[i]]=i;
vector<int> stk;
stk.push_back(n+1);
int now=1,ptr=1;
for(now=1;now<=n;now++){
if(!loc[now]) break;
while(ptr<=loc[now]) stk.push_back(a[ptr++]);
if(stk.back() != now) return 0*printf("-1\n");
stk.pop_back();
}
while (ptr<=k) stk.push_back(a[ptr++]);
stk.push_back(now-1);
for(int i=0;i+1<(int)stk.size();i++)
if(stk[i]<stk[i+1]) return 0*printf("-1\n");
for(int i=(int)stk.size()-1;i>0;i--){
for(int j=stk[i-1]-1;j>stk[i];j--) a[++k]=j;
}
for(int i=1;i<=n;i++) printf("%d%c",a[i]," \n"[i==n]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  codeforces