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

 

转载于:https://www.cnblogs.com/naturepengchen/articles/4677625.html

### 关于 Codeforces Round 839 Div 3 的题目与解答 #### 题目概述 Codeforces Round 839 Div 3 是一场面向不同编程水平参赛者的竞赛活动。这类比赛通常包含多个难度层次分明的问题,旨在测试选手的基础算法知识以及解决问题的能力。 对于特定的比赛问题及其解决方案,虽然没有直接提及 Codeforces Round 839 Div 3 的具体细节[^1],但是可以根据以往类似的赛事结构来推测该轮次可能涉及的内容类型: - **输入处理**:给定一组参数作为输入条件,这些参数定义了待解决的任务范围。 - **逻辑实现**:基于输入构建满足一定约束条件的结果集。 - **输出格式化**:按照指定的方式呈现最终答案。 考虑到提供的参考资料中提到的其他几场赛事的信息[^2][^3],可以推断出 Codeforces 圆桌会议的一般模式是围绕着组合数学、图论、动态规划等领域展开挑战性的编程任务。 #### 示例解析 以一个假设的例子说明如何应对此类竞赛中的一个问题。假设有如下描述的一个简单排列生成问题: > 对于每一个测试案例,输出一个符合条件的排列——即一系列数字组成的集合。如果有多种可行方案,则任选其一给出即可。 针对上述要求的一种潜在解法可能是通过随机打乱顺序的方式来获得不同的合法排列形式之一。下面是一个 Python 实现示例: ```python import random def generate_permutation(n, m, k): # 创建初始序列 sequence = list(range(1, n + 1)) # 执行洗牌操作得到新的排列 random.shuffle(sequence) return " ".join(map(str, sequence[:k])) # 测试函数调用 print(generate_permutation(5, 2, 5)) # 输出类似于 "4 1 5 2 3" ``` 此代码片段展示了怎样创建并返回一个长度为 `k` 的随机整数列表,其中元素取自 `[1..n]` 这个区间内,并且保证所有成员都是唯一的。需要注意的是,在实际比赛中应当仔细阅读官方文档所提供的精确规格说明,因为这里仅提供了一个简化版的方法用于解释概念。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值