和谐

harmony.pas/c/cpp

【问题描述】

小k同学本来想给这个题套一个很好玩的背景的,但是因为一些原因(看题目名,你们懂的),这题的题面就变得非常无聊了。

对于任意四个两两不同的数clip_image002,记clip_image004,考虑以下6个值:clip_image006,在这6个值中sum的约数个数记为这四个数的和谐度。例如0,7,2,3这4个数的和谐度为2.因为0+2和0+3是这4个数的和12的约数。

现在小k想知道两个问题:1. 如果他任意写下4个数,和谐度最大可能是多少;2. 满足clip_image008并且A、B、C、D这4个数的和谐度为第1问中的值的所有四元组clip_image010一共有多少组。

【输入格式】

输入一行2个整数L和R,意义如上所述。

【输出格式】

输出2行,每行一个整数,分别表示2问的答案。

【样例输入】

harmony.in

1 30

【样例输出】

harmony.out

4

3

【样例解释】

和谐度最大只能达到4,没有和谐度超过4的4个数

在[1, 30]中,满足和谐度为4的4个数共有3组:

1. 1 5 7 11

2. 2 10 14 22

3. 1 11 19 29

【数据规模和约定】

对于60%的数据,clip_image012

对于100%的数据,clip_image014.

分解因式

factorize.pas/c/cpp

【问题描述】

众所周知,整系数范围内分解因式是一个非常难的问题。为了解决这个问题,人们想出了各种公式和方法,例如平方差公式、立方差公式、立方和公式、提取公因式、十字相乘法等等。现在“伟大”的只会空想的不切实际的伪数学爱好者小k同学希望能借助计算机解决这个问题。

为了让自己的题目显得不那么丧心病狂一点,小k同学决定只要你解决一类特殊的因式分解问题,那就是分解clip_image016. 在整系数范围内分解到不能继续分解为止。换句话说,最后的答案中每个因式不含更低次数的因式。

不过小k后来意识到这个问题还是很丧心病狂,为了降低题目难度,小k给出一个提示:一个多项式clip_image018是另一个多项式clip_image020的因式当且仅当a是b的一个约数。

【输入格式】

输入一行一个数n,待分解的多项式就是clip_image016[1]

【输出格式】

输出一行一个字符串,表示因式分解的结果。最后的输出中每个因式应该不含空格,系数为1或-1时应省略1,系数为0的项应该省略,每个因式应该降幂排列,并且保证首项系数为正。除此以外,我们要求按如下顺序排列因式:优先输出次数低的因式,对于次数相同的因式,依次比较每个因式的系数,从高指数项到低指数项,且包括被省略即系数为0的项。系数首先比较绝对值,其次比较符号。绝对值小的系数字典序序小,绝对值相同时比较符号,负号字典序比正号小。字典序越小的因式应该排在越前面输出。

【样例输入】

factorize.in

20

【样例输出】

factorize.out

(x - 1) (x + 1) (x^2 + 1) (x^4 – x^3 + x^2 - x + 1) (x^4 + x^3 + x^2 + x + 1) (x^8 – x^6 + x^4 – x^2 + 1)

【数据规模和约定】

对于40%的数据,clip_image022

对于100%的数据,clip_image024.

投票

vote.pas/c/cpp

【问题描述】

小k同学正在玩一个游戏,在游戏中他扮演了一个马戏团的老板,现在小k同学需要利用马戏团中的A只猫和B只狗举办一次表演,表演之前他让观众进行了投票,投票的类容是:我想看到第___号猫/狗的表演,不想看到第___号猫/狗的表演。注意到每个观众都是更喜欢猫或更喜欢狗,所以两个空后面一定会被勾上不同的内容。喜欢猫的观众会在第一空后面选择猫,第二空后面选择狗;反之就会在第一空后面选择狗,第二空后面选择猫。对于每一个观众,只有当TA投票的内容都被满足了(即TA想看到的动物出场表演,TA不想看到的动物不参与表演)的时候,TA才会来看表演。当然啦,看表演是要付门票钱的,作为马戏团的老板,小k自然是希望来的人越多越好了。他想找到一个安排动物表演的方案,使得来看表演的观众尽量多。

【输入格式】

第1行3个正整数n、m、k,分别表示猫、狗和观众的数量

第2~k+1行,每行描述了一个观众的投票内容。

首先输入一个字符C或D紧接着是一个数字,表示某个观众想看到的动物,然后是一个空格隔开,接下去又是一个C或D加上一个数字,表示这个观众不想看到的动物,同一行中一定不会出现两个C或两个D。

【输出格式】

输出一行一个正整数,表示小k在最优的安排下可以吸引多少观众来看表演。

【样例输入】

vote.in

1 2 4

C1 D1

C1 D1

C1 D2

D2 C1

【样例输出】

vote.out

3

【数据规模和约定】

对于25%的数据,clip_image026;

对于100%的数据,clip_image028.

 

#include <cstdio> 
#include <algorithm>
using namespace std;
int n,m,k;
int love[1000][2],hate[1000][2];
int map[1000][1000];
int id[1000];
bool v[1000];
bool use[1000];
int match[1000];
int ans;
bool dfs(int x){
     for (int i=1;i<=map[x][0];i++){
         if (!use[map[x][i]]){
                              use[map[x][i]]=true;
                              if (match[map[x][i]]==0 || dfs(match[map[x][i]])){
                                                      match[map[x][i]]=x;
                                                      return true;
                              }
         }
     }
     return false;
}
int main(){
    freopen("vote.in","r",stdin);
    freopen("vote.out","w",stdout);
    scanf("%d%d%d\n",&n,&m,&k);
    n=m=0;
    for (int i=1;i<=k;i++){
        char c1,c2;
        int t1,t2;
        scanf("%c%d %c%d\n",&c1,&t1,&c2,&t2);
        if (c1=='C'){
                     love[++n][0]=t1;
                     hate[n][0]=t2;
        }else{
              love[++m][1]=t1;
              hate[m][1]=t2;
        }
    }
    for (int i=1;i<=n;i++){
        for (int j=1;j<=m;j++){
            if (love[i][0]==hate[j][1] || hate[i][0]==love[j][1]) map[i][++map[i][0]]=j;
        }
    }
    int ans=0;
    for (int i=1;i<=n;i++){
        memset(use,0,sizeof(use));
        if (dfs(i)) ans++;
    }
    printf("%d\n",k-ans);
    return 0;
}

树形图计数

count.pas/c/cpp

【问题描述】

小k同学最近正在研究最小树形图问题。所谓树形图,是指有向图的一棵有根的生成树,其中树的每一条边的指向恰好都是从根指向叶结点的方向。现在小k在纸上画了一个图,他想让你帮忙数一下这个图有多少棵树形图。

【输入格式】

第1行输入1个正整数:n,表示图中点的个数

第2~n+1行每行输入n个字符,描述了这个图的邻接矩阵。第i+1行第j个字符如果是0则表示没有从i连向j的有向边,1表示有一条从i到j的有向边。

【输出格式】

输出1行1个整数,表示这个有向图的树形图个数。

【样例输入】

count.in

4

0100

0010

0001

1000

【样例输出】

count.out

4

【数据规模和约定】

对于100%的数据,clip_image030

 

#include <cstdio>
int fa[15];
char s[15][15];
int n;
int root;
int ans;
int get(int x){
    while (fa[x]!=x) x=fa[x];
    return x;
}
void dfs(int d){
     if (root==d){
                  dfs(d+1);
                  return;
     }
     if (d==n) ans++;
     for (int i=0;i<n;i++){
         if (s[i][d]=='1' && get(i)!=get(d)){
                          fa[d]=i;
                          dfs(d+1);
                          fa[d]=d;
         }
     }
}
int main(){
    freopen("count.in","r",stdin);
    freopen("count.out","w",stdout);
    scanf("%d",&n);
    for (int i=0;i<n;i++)
        scanf("%s",s[i]);
    for (int i=0;i<n;i++) fa[i]=i;
    for (root=0;root<n;root++) dfs(0);
    printf("%d\n",ans);
    return 0;
}