Codeforces #313 div1

2015-07-26 14:05:40

传送门

总结:前三题都是可做的。赛中三题,由于最近的多校,没补后面的题了... 第二题有点坑爹... hack 数据是针对某些 dfs 顺序的。用 string 的就可能被卡。

 

A题:简单题。将其补全成正三角形就 ok 了。

 

#include <cstdio>
#include <ctime>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;

#define getmid(l,r) ((l) + ((r) - (l)) / 2)
#define MP(a,b) make_pair(a,b)
#define PB push_back

typedef long long ll;
typedef pair<int,int> pii;
const double eps = 1e-8;
const int INF = (1 << 30) - 1;

int a,b,c,d,e,f;

int main(){
    scanf("%d%d%d%d%d%d",&a,&b,&c,&d,&e,&f);
    int D = e + d + c;
    int ans = D * D - a * a - e * e - c * c;
    printf("%d\n",ans);
    return 0;
}
View Code

 

 

B题:根据题意模拟即可,注意 DFS 传的参数要少。

 

#include <cstdio>
#include <ctime>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;

#define getmid(l,r) ((l) + ((r) - (l)) / 2)
#define MP(a,b) make_pair(a,b)
#define PB push_back

typedef long long ll;
typedef pair<int,int> pii;
const double eps = 1e-8;
const int INF = (1 << 30) - 1;
const int MAXN = 200010;

char s1[MAXN],s2[MAXN];
int len1,len2;

bool Dfs(int a1,int b1,int a2,int b2){
    if(a1 == b1){
        return s1[a1] == s2[a2];
    }
    if((b1 - a1 + 1) & 1){
        for(int i = a1; i <= b1; ++i)
            if(s1[i] != s2[i - a1 + a2]) return false;
        return true;
    }
    int mid1 = (a1 + b1) >> 1,mid2 = (a2 + b2) >> 1;
    if(Dfs(a1,mid1,a2,mid2) && Dfs(mid1 + 1,b1,mid2 + 1,b2)) return true;
    if(Dfs(a1,mid1,mid2 + 1,b2) && Dfs(mid1 + 1,b1,a2,mid2)) return true;
    return false;
}

int main(){
    scanf("%s%s",s1 + 1,s2 + 1);
    len1 = strlen(s1 + 1);
    len2 = strlen(s2 + 1);
    if(Dfs(1,len1,1,len2)){
        printf("YES\n");
    }
    else{
        printf("NO\n");
    }
    return 0;
}
View Code

 

 

C题:组合数,DP

  题意:从(1,1)走到(h,w)且不经过黑格子的走法数,只能向右 / 向下走,黑格子数<=2000。

  思路:显然是根据黑格子来思考,由于不存在黑格子时从(1,1)到(n,m)的走法是C(n+m,n),所以可以这么考虑:

  从最后一个黑格子(最靠近终点的黑格子)开始倒着考虑,DP[i] 表示从第 i 个黑格子出发不经过其他黑格子到终点的走法数,那么最后一个黑格子的 dp 就可以直接用组合数算出来,计算其他点的 dp 值时需要枚举最后经过哪个黑格子,比如考虑第 i 个黑格子,就要枚举第 i+1 <= j <= k 个黑格子作为最后经过的黑格子,那么 dp[i] = Sigma(cnt(i , j) * dp[j]),cnt(i , j) 表示从第 i 个黑格子到第 j 个黑格子的走法数。

  最后的答案就是 Sigma(cnt(st , i) * dp[i])(1 <= i <= k),k 为黑格子数。

#include <cstdio>
#include <ctime>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;

#define getmid(l,r) ((l) + ((r) - (l)) / 2)
#define MP(a,b) make_pair(a,b)
#define PB push_back

typedef long long ll;
typedef pair<int,int> pii;
const double eps = 1e-8;
const int INF = (1 << 30) - 1;
const ll mod = 1e9 + 7;
const int MAXN = 200000;

ll fac[MAXN + 10],afac[MAXN + 10];
ll dp[2010][2010],res[2010];
int h,w,n;

struct node{
    int X,Y;
}P[2010];

ll Q_pow(ll x,ll y){
    x %= mod;
    ll res = 1;
    while(y){
        if(y & 1) res = res * x % mod;
        x = x * x % mod;
        y >>= 1;
    }
    return res;
}

void Pre(){
    fac[0] = afac[0] = 1;
    for(int i = 1; i <= MAXN; ++i) fac[i] = fac[i - 1] * (ll)i % mod;
    afac[MAXN] = Q_pow(fac[MAXN],mod - 2);
    for(int i = MAXN; i >= 1; --i) afac[i - 1] = afac[i] * i % mod;
}

ll C(int n,int m){
    if(m == 0 || m == n) return 1;
    return fac[n] * afac[n - m] % mod * afac[m] % mod;
}

bool cmp(node a,node b){
    if(a.X == b.X) return a.Y > b.Y;
    return a.X > b.X;
}

int main(){
    Pre();
    scanf("%d%d%d",&h,&w,&n);
    for(int i = 1; i <= n; ++i){
        scanf("%d%d",&P[i].X,&P[i].Y);
    }
    sort(P + 1,P + n + 1,cmp);
    ll ans = C(h + w - 2,h - 1);
    for(int i = 1; i <= n; ++i){ //从这个点到终点
        int a1 = h - P[i].X + w - P[i].Y;
        int a2 = h - P[i].X;
        res[i] = C(a1,a2);
        for(int j = 1; j < i; ++j){
            a1 = P[j].X - P[i].X + P[j].Y - P[i].Y;
            a2 = P[j].X - P[i].X;
            res[i] = (res[i] - C(a1,a2) * res[j] % mod + mod) % mod;
        }
    }
    for(int i = 1; i <= n; ++i){
        int a1 = P[i].X - 1 + P[i].Y - 1;
        int a2 = P[i].X - 1;
        ans = (ans - C(a1,a2) * res[i] % mod + mod) % mod;
    }
    printf("%I64d\n",ans);
    return 0;
}
View Code

 

posted @ 2015-07-26 14:23  Naturain  阅读(121)  评论(0编辑  收藏  举报