【Link】:http://codeforces.com/contest/839/problem/B

【Description】



给你n排的如题目所示的位置;

同一排中(1,2) 算相邻;

(3,4),(4,5),(5,6)算相邻,然后(7,8)算相邻;

这里的(x,y)表示某个人坐在x,另外一个人坐在y的话.

问你够不够安排k组的人;

使得相邻座位的人都是相同组的人;

是则输出YES….

【Solution】



中间的那4个位置;

是没办法用来放不同组的成对的.

也即

xxyy不能放在中间那4个位置.

但xx和yy可以放在最左边和最右边的那两个连续位置;

则,我们中间那4个位置;

先尽可能地放同一组的4个人

这样,能尽量避免不同组的人到中间那4个位置

不同组的人到了中间那4个位置肯定不能最大化利用这4个位置的

因为肯定会有空座位

剩余的不同组的人,则可以安排在两侧的连续位置

中间那4个位置安排过后;

有两种情况.

第一种

n排所有的中间4个位置的都被安排光了;

剩下的组中可能还有大于4的人.

这个时候,只有最左边和最右边的连续两个块可以使用了;

则还剩下n*2个连续的对的空间;

如果某一组为奇数;

则那个多出来的人单独占据一对的空间即可;

否则就贪心地用这n*2个连续对就好;

第二种

这n排中,有一些排中间的4个位置还是空的.

这个时候,所有组的人数都已经小于4了;

我们先考虑一组中还有2..3个人的.

先把其中两个人优先安排到最左和最右的(1,2)或(7,8)位置;

我们有n*2个那样的(1,2)或(7,8)位置;

(即每行两边都有两个)

但可能这n*2个还不够用;

可能还是有一些组有2..3个人;

则,我们再给他安排在(4,5)的位置;

注意,

这个时候,我们一旦安排在了(3,4);

那么那一行就只有位置6还能放单个的人了;

可能(4,5)的位置放完了以后还是不够;

也即还是有一些组有2..3个人

这个时候;就利用我们刚才在中间放了(3,4),而6还能放单个的人这一点;

两个那个位置5,就又能凑成一对了;

(这种放一对的方案,很容易被漏掉)

如果还是有一些组有2..3个人,那么就不行了;

输出无解;

否则,考虑剩下的组中还剩一个人的组

那一个人可以放在n*2个里面(如果对还没用完的话),或者放在

中间连续的4个空位也即(3,4)和(5,6)中的3和6,这个时候中间的4个位置可以用其中的两个,所以减去了连续的4个空位置的个数之后,还有递增单个位置,也即上面提到的当个的位置6

或者

放在单个的位置6

这3种考虑后如果还不行就无解;

(就是说那一个人放不下的话)



【NumberOf WA】



4



【Reviw】



分成两行放一对那种方法没想到.

一开始认为超过8就直接放一整行的天真想法是错的。



【Code】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ms(x,y) memset(x,y,sizeof x)
#define ri(x) scanf("%d",&x)
#define rl(x) scanf("%lld",&x)
#define rs(x) scanf("%s",x+1)
#define oi(x) printf("%d",x)
#define ol(x) printf("%lld",x)
#define oc putchar(' ')
#define os(x) printf(x)
#define all(x) x.begin(),x.end()
#define Open() freopen("F:\\rush.txt","r",stdin)
#define Close() ios::sync_with_stdio(0) typedef pair<int,int> pii;
typedef pair<LL,LL> pll; const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
const int N = 100; int n,k,a[N+10],cur4,cur2,cur; int main(){
//Open();
//Close();
ri(n),ri(k);
rep1(i,1,k) {
ri(a[i]);
} cur4 = n;
if (cur4)
rep1(i,1,k)
if (a[i]>=4){
int temp = min(a[i]/4,cur4);
cur4-=temp;
a[i] -= temp*4;
if (cur4==0) break;
} if (cur4 > 0){//全都小于4了
int pairs = n*2;
for (int i = 1;i <= k && pairs > 0;i++)
if (a[i] > 1){
pairs--;
a[i]-=2;
}
int singlec = 0; rep1(i,1,k)
if (a[i] > 1){
if (cur4 > 0){
cur4--;
singlec++;
a[i]-=2;
continue;
}
if (singlec >= 2){
singlec-=2;
a[i]-=2;
continue;
}
return puts("NO");
} rep1(i,1,k)
if (a[i]==1){
if (pairs){
pairs--;
continue;
}
if (singlec){
singlec--;
continue;
}
if (cur4){
cur4--;
singlec++;
continue;
}
return puts("NO"),0;
}
puts("YES");
}else{ //cur4==0
int pairs = n*2;
rep1(i,1,k)
if (a[i] > 0){
pairs-=((a[i]-1)/2+1);
if (pairs < 0) return puts("NO"),0;
}
puts("YES");
}
return 0;
}

最新文章

  1. hessian学习
  2. Windows7中IIS简单安装与配置(详细图解)
  3. CentOS7 续
  4. 深入理解java虚拟机(7)---线程安全 &amp; 锁优化
  5. linux下Redis与phpredis扩展安装
  6. 应用emailAutoComplete.js来自动显示邮箱后缀列表
  7. java大数总结【转】
  8. Android应用自动更新功能的实现!!!
  9. asp.net 树形控件 $.fn.zTree.init
  10. (一) 这就是所谓的Node.js------单线程,非阻塞,事件驱动
  11. PostgreSQL对汉字按拼音排序
  12. Java集合不能存放基本数据类型
  13. Vue 鼠标移入移出事件
  14. hello2源代码解析
  15. babel 编译后 this 变成了 undefined
  16. Delphi XE5 for Android (五)
  17. 删除node_modules
  18. 从一个例子学习 instanceof 和 getclass 的区别
  19. Lambda表达式学习(1)
  20. Centos最小化安装后还需要安装的软件包收集

热门文章

  1. Python IO编程-组织文件
  2. Ehcache学习总结(1)--Ehcache入门介绍
  3. 前端编程提高之旅(十二)----position置入值应用
  4. MFC Wizard创建的空应用程序中各个文件内容的解析
  5. 【POJ3377】Ferry Lanes 最短路
  6. how to backup and restore database of SQL Server
  7. html2canvas截取页面
  8. Windows Server8下补丁分发配置与iSCSI配置
  9. vue-router学习例子分享
  10. 学习总结--Dom