AtCoder Regular Contest 076

C – Reconciled?

Snuke has N dogs and M monkeys. He wants them to line up in a row.

As a Japanese saying goes, these dogs and monkeys are on bad terms. (“ken’en no naka”, literally “the relationship of dogs and monkeys”, means a relationship of mutual hatred.) Snuke is trying to reconsile them, by arranging the animals so that there are neither two adjacent dogs nor two adjacent monkeys.

How many such arrangements there are? Find the count modulo 109+7 (since animals cannot understand numbers larger than that). Here, dogs and monkeys are both distinguishable. Also, two arrangements that result from reversing each other are distinguished.

n只狗和m只猫排列,同种动物不能相邻出现,问有多少种排列方式(模1e9+7)
n和m相等时答案2 × n!× m!
n和m相差1时n! × m!
否则为0

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100000+5;
const ll mod = 1e9+7;
ll n, m;
ll fac[maxn];
int main(){
  ios::sync_with_stdio(false);
  cin.tie(0);cout.tie(0);
  fac[0] = 1;
  for(int i = 1; i < maxn; i++) fac[i] = i * fac[i-1] % mod;
  cin >> n >> m;
  if(n == m){
    cout << ((fac[n] * fac[n] )%mod * 2) % mod;
  }
  else if(n-m == 1 || n-m == -1){
    cout << fac[n] * fac[m] % mod;
  }
  else{
    cout << "0" << endl;
  }
  return 0;
}

D – Built?

There are N towns on a plane. The i-th town is located at the coordinates (xi,yi). There may be more than one town at the same coordinates.

You can build a road between two towns at coordinates (a,b) and (c,d) for a cost of min(|a−c|,|b−d|) yen (the currency of Japan). It is not possible to build other types of roads.

Your objective is to build roads so that it will be possible to travel between every pair of towns by traversing roads. At least how much money is necessary to achieve this?

求最小生成树的权值和,任意两点的权值为min(|x1-x2|,|y1-y2|),按横坐标和纵坐标分别排序然后kruskal+并查集

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100001;
const ll mod = 1e9+7;
int n, tot;
struct coo
{
    int x, y;
    int id;
}c[maxn];
bool cmp1(coo a, coo b){
  return a.x < b.x;
}
bool cmp2(coo a, coo b){
  return a.y < b.y;
}
int dx[maxn],dy[maxn];
struct Edge{
  int u, v;
  int cost;
}e[maxn*2];
bool cmp(Edge a, Edge b){
  return a.cost < b.cost;
}
int p[maxn];
int find(int x){return p[x] == x ? x : p[x] = find(p[x]);}
int main(){
  ios::sync_with_stdio(false);
  cin.tie(0);cout.tie(0);
  scanf("%d", &n);
  for(int i = 0; i <= n; i++) p[i] = i;
  for(int i = 1; i <= n; i++){
    scanf("%d%d", &dx[i], &dy[i]);
  }
  for(int i = 1; i <= n; i++)
  {
    c[i].x = dx[i]; c[i].y = dy[i];c[i].id = i;
  }
  sort(c+1,c+1+n,cmp1);
  for(int i = 2; i <= n; i++){
    e[tot].u = c[i].id;
    e[tot].v = c[i-1].id;
    e[tot].cost = c[i].x - c[i-1].x;
    tot++;
  }
  sort(c+1,c+1+n,cmp2);
  for(int i = 2; i <= n; i++){
    e[tot].u = c[i].id;
    e[tot].v = c[i-1].id;
    e[tot].cost = c[i].y - c[i-1].y;
    tot++;
  }
  sort(e,e+tot,cmp);
  ll ans = 0;
  int cnt = 0;
  for(int i = 0; i < tot; i++){
    int f = find(e[i].u);
    int t = find(e[i].v);
    if(f!=t){ans+=e[i].cost;p[f] = t;cnt++;}
    if(cnt == n-1)break;
  }
  printf("%lld\n", ans);
  return 0;
}

E – Connected?

Snuke is playing a puzzle game. In this game, you are given a rectangular board of dimensions R×C, filled with numbers. Each integer i from 1 through N is written twice, at the coordinates (xi,1,yi,1) and (xi,2,yi,2).

The objective is to draw a curve connecting the pair of points where the same integer is written, for every integer from 1 through N. Here, the curves may not go outside the board or cross each other.

Determine whether this is possible.

R × C的网格里有N 种数,每种数出现两次,给出它们在网格里的坐标,问是否能够使得所有相同的数相互连通,并且不会有交叉或者穿过其他边

顺时针考虑两次都出现在边界上的点,假设存在两点i,j如果出现顺序是i,j,i,j则不能满足要求,如果是i,j,j,i 或 i,i,j,j则满足,可以用栈来实现

#include <bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;
const int maxn = 100001;
const ll mod = 1e9+7;
int r,c,n;
struct point{
  int id;
  int val;
};
vector<point> v[4];
bool check(int x, int y){
  if(x == 0 || x == r || y == 0 || y == c) return true;
  return false;
}
void push(int id, int x, int y){
  if(x == 0) v[0].pb({id, y});
  else if(y == c) v[1].pb({id, x});
  else if(x == r) v[2].pb({id, y});
  else if(y == 0) v[3].pb({id, x});
}
bool cmp1(point a, point b){
  return a.val < b.val;
}
bool cmp2(point a, point b){
  return a.val > b.val;
}
int main(){
  ios::sync_with_stdio(false);
  cin.tie(0);cout.tie(0);
  cin >> r >> c >> n;
  int x1,x2,y1,y2;
  for(int i = 1; i <= n; i++){
    cin >> x1 >> y1 >> x2 >> y2;
    if(check(x1,y1) && check(x2,y2))
      push(i,x1,y1),push(i,x2,y2);
  }
  sort(v[0].begin(), v[0].end(),cmp1);
  sort(v[1].begin(), v[1].end(),cmp1);
  sort(v[2].begin(), v[2].end(),cmp2);
  sort(v[3].begin(), v[3].end(),cmp2);
  stack<int> s;
  for(int j = 0; j < 4; j++)
    for(int i = 0; i < v[j].size(); i++){
    if(s.size() == 0) {s.push(v[j][i].id); continue;}
    if(s.top() == v[j][i].id) s.pop();
    else s.push(v[j][i].id);
  }

  cout << (s.empty() ? "YES" : "NO" )<< endl;
  return 0;
}

F – Exhausted?

There are M chairs arranged in a line. The coordinate of the i-th chair (1≤i≤M) is i.

N people of the Takahashi clan played too much games, and they are all suffering from backaches. They need to sit in chairs and rest, but they are particular about which chairs they sit in. Specifically, the i-th person wishes to sit in a chair whose coordinate is not greater than Li, or not less than Ri. Naturally, only one person can sit in the same chair.

It may not be possible for all of them to sit in their favorite chairs, if nothing is done. Aoki, who cares for the health of the people of the Takahashi clan, decides to provide additional chairs so that all of them can sit in chairs at their favorite positions.

Additional chairs can be placed at arbitrary real coordinates. Find the minimum required number of additional chairs.

N 个人,M把椅子,每个人都要有椅子坐,第i个人不能坐[Li+1,Ri-1]里的椅子,最少要添多少椅子

贪心,先按左端点(L)排序,尽量先往左边垒,如果左边垒不下就垒右边,在已经垒好的集合里换一个右端点(R)最小的,最终还没有垒的全放在右端点。

#include <bits/stdc++.h>
#define MN 210000
using namespace std;
struct na{int l,r;}p[MN];
bool cmpl(na a,na b){return a.l==b.l?a.r>b.r:a.l<b.l;}
priority_queue<int,vector<int>,greater<int> > q,_q;
int n,m,mmh;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cin >> n >> m;
    mmh = n;
    for (int i=1;i<=n;i++) cin >> p[i].l >> p[i].r;
    sort(p+1,p+1+n,cmpl);
    for (int i=1;i<=n;i++)
    if (p[i].l==q.size()) q.push(p[i].r),_q.push(q.top()),q.pop();else q.push(p[i].r),mmh--;
    for (int i=q.size()+1;i<=m&&!_q.empty();i++) if (_q.top()<=i) _q.pop(),mmh--;
    cout << mmh << endl;
}
posted @ 2018-03-16 08:56  foreignbill  阅读(254)  评论(0)    收藏  举报