[Regionals 2012 :: Asia - Tokyo ]

链接:

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=566

A  uva live 6182 - Ginkgo
Numbers

题目意思:

规则:

1、<m, n>
· <x, y>
= <mx ? ny, my + nx>

2、如果<m,n>是<p,q>的“除数”,则存在<x,y>,使得<m, n>
· <x, y>
= <p, q>.

3、如果<m, n>
· <x, y>
= <p, q>,
则 (m2 + n2)(x2 + y2)
= p2 + q2.

给定n,m,判断n,m是否恰好只有<1,
0>, <0, 1>, <-1, 0>, <0,-1>, <m, n>,
<-n,m>,
<-m,-n>
and <n,-m>这8个“除数”。

解题思路:

简单数学。

实际上只用根据第三条规则来就可以了,因为n*n+m*m<2000,只用把n^2+m^2分解成两个约数的乘积,看这两个约数是否能分别凑成两个数的平方和。

代码:

#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;

#define Maxn 22000

bool isc[Maxn];
bool isp[Maxn];
int pri[Maxn],cnt;

void init()
{
    memset(isc,false,sizeof(isc));
    for(int i=1;i*i<=20000;i++)
    {
        int a=i*i;
        isc[a]=true;
        for(int j=i;j*j+a<=20000;j++)
            isc[a+j*j]=true;
    }
    cnt=0;
    memset(isp,true,sizeof(isp));
    for(int i=2;i<=20000;i++)
    {
        if(isp[i])
        {
            pri[++cnt]=i;
            for(int j=i*2;j<=20000;j+=i)
                isp[j]=false;
        }
    }
}
int main()
{
    int t,n,m;

    scanf("%d",&t);
    init();

    while(t--)
    {
        scanf("%d%d",&n,&m);
        int sum=n*n+m*m;

        if(isp[sum])
        {
            printf("P\n");
            continue;
        }
        bool flag=true;
        for(int i=2;i*i<=sum;i++)
        {
            if(sum%i==0&&isc[i]&&isc[sum/i])
            {
                flag=false;
                break;
            }

        }
        if(flag)
            printf("P\n");
        else
            printf("C\n");
    }
    return 0;
}

B uva live 6183 - Stylish

题目意思:

根据第一段代码圆括号、方括号、大括号的缩进法则,输出第二段代码缩进。

解题思路:

模拟

题目很难看懂,但注意题目细节就可以看懂。但本题数据范围比较小。

先把所有情况都罗列出来,置为可以满足的,然后根据第一段的每一行的法则,排除不能满足的情况。最后再对每一行,找出符合要求的RSC,如果有两种答案,则为非法。

代码:

//#include<CSpreadSheet.h>

#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#include<cmath>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

bool isc[22][22][22];
int n,m;
char sa[110];

int main()
{
    //freopen("in.txt","r",stdin);
   //freopen("out.txt","w",stdout);
   while(scanf("%d%d",&n,&m)&&n+m)
   {
       memset(isc,true,sizeof(isc));
       int rr=0,ss=0,cc=0;

       for(int i=1;i<=n;i++)
       {
           scanf("%s",sa);
           //printf("%s",sa);
           int p=0;
           while(sa[p]&&sa[p]=='.')
                p++;
           for(int j=1;j<=20;j++)
                for(int k=1;k<=20;k++)
                    for(int q=1;q<=20;q++)
                   {
                       if(j*rr+k*ss+q*cc!=p)
                       {
                           isc[j][k][q]=false;
                       }
                   }
          //printf("i:%d p:%d %c\n",i,p,sa[p]);
          while(sa[p])
          {
              if(sa[p]=='(')rr++;
              else if(sa[p]==')')rr--;
              else if(sa[p]=='[')ss++;
              else if(sa[p]==']')ss--;
              else if(sa[p]=='{')cc++;
              else if(sa[p]=='}')cc--;
              p++;
          }
       }
       scanf("%s",sa);
       printf("0");
       int p=0;
       rr=ss=cc=0;
       while(sa[p])
        {
          if(sa[p]=='(')rr++;
          else if(sa[p]==')')rr--;
          else if(sa[p]=='[')ss++;
          else if(sa[p]==']')ss--;
          else if(sa[p]=='{')cc++;
          else if(sa[p]=='}')cc--;
          p++;
        }
        for(int i=2;i<=m;i++)
        {
            //printf("i:%d rr:%d ss:%d cc:%d %d\n",i,rr,ss,cc,isc[9][1][1]);
            //system("pause");
            int ans=-1;
            bool flag=true;

            for(int j=1;j<=20&&flag;j++)
                for(int k=1;k<=20&&flag;k++)
                    for(int q=1;q<=20&&flag;q++)
                   {
                       if(isc[j][k][q])
                       {
                           if(ans==-1)
                                ans=j*rr+k*ss+q*cc;
                           else if(j*rr+k*ss+q*cc!=ans)
                           {
                               flag=false;
                               break;
                           }
                       }
                   }
            if(!flag)
                printf(" -1");
            else
                printf(" %d",ans);
            scanf("%s",sa);
            p=0;
            while(sa[p])
              {
                  if(sa[p]=='(')rr++;
                  else if(sa[p]==')')rr--;
                  else if(sa[p]=='[')ss++;
                  else if(sa[p]==']')ss--;
                  else if(sa[p]=='{')cc++;
                  else if(sa[p]=='}')cc--;
                  p++;
              }
        }
        putchar('\n');

   }
    return 0;
}

C uva live 6184 - One-Dimensional
Cellular Automaton

题目意思:

给一个t=0时刻,0-n-1的原始数据,求根据S(i, t +
1) = (A × S(i ?
1, t)
+ B × S(i, t)
+ C × S(i +
1, t))
mod M,求出S(i,t).

解题思路:

快速幂

构造n*n的矩阵。直接转移就行。

代码:

#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;

#define ll long long
#define Maxn 55

ll M,n,a,b,c,t;

struct Mar
{
    int row,col;
    ll s[Maxn][Maxn];

    void init(int a,int b)
    {
        row=a,col=b;
        memset(s,0,sizeof(s));
    }
};

Mar operator *(const Mar &a,const Mar &b)
{
    Mar res;
    res.init(a.row,b.col);
    for(int k=1;k<=a.col;k++)
    {
        for(int i=1;i<=res.row;i++)
        {
            if(a.s[i][k]==0)
                continue;
            for(int j=1;j<=res.col;j++)
            {
                if(b.s[k][j]==0)
                    continue;
                res.s[i][j]=(a.s[i][k]*b.s[k][j]+res.s[i][j])%M;
            }
        }
    }
    return res;
}
int main()
{
    while(scanf("%lld%lld%lld%lld%lld%lld",&n,&M,&a,&b,&c,&t))
    {
        if(!n&&!M&&!a&&!b&&!c&&!t)
            break;
        Mar ba;
        ba.init(n+2,n+2);
        ba.s[1][1]=b,ba.s[1][2]=c;
        for(int i=2;i<=n-1;i++)
        {
            ba.s[i][i-1]=a,ba.s[i][i]=b;
            ba.s[i][i+1]=c;
        }
        ba.s[n][n-1]=a,ba.s[n][n]=b;

        Mar ans;
        ans.init(n+2,1);
        for(int i=1;i<=n;i++)
            scanf("%lld",&ans.s[i][1]);
        while(t)
        {
            if(t&1)
                ans=ba*ans;
            ba=ba*ba;
            t>>=1;
        }
        bool fi=true;
        for(int i=1;i<=n;i++)
        {
            if(!fi)
                printf(" ");
            else
                fi=false;
            printf("%lld",ans.s[i][1]);
        }
        putchar('\n');

    }
    return 0;
}

F uva live 6187 - Never
Wait for Weights

题目意思:

规则:

! a b v 表示a物品比b物品重量少v

?a b    询问a物品比b物品少多少重量,如果不知道,则输出UNKNOWN

解题思路:

并查集,维护每个节点与当前根的数值大小关系

查找完毕后,该节点与根的关系就算出来了

合并时先查找,然后把根连过去。

代码:

//#include<CSpreadSheet.h>

#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#include<cmath>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

#define Maxn 1100000

int fa[Maxn],n,m;
LL va[Maxn];

int Find(int x)
{
    if(fa[x]==x)
        return x;
    int fx=Find(fa[x]);
    va[x]+=va[fa[x]];
    return fa[x]=fx;
}

void Unio(int x,int y,LL v)
{
    int fx=Find(x),fy=Find(y);

    if(fx==fy)
        return ;
    va[fx]=v+va[y]-va[x];
    fa[fx]=fy;
}

int main()
{
    //freopen("in.txt","r",stdin);
   //freopen("out.txt","w",stdout);
   while(scanf("%d%d",&n,&m)&&n+m)
   {
       for(int i=1;i<=n;i++)
            fa[i]=i;
       memset(va,0,sizeof(va));
       char sa[10];
       for(int i=1;i<=m;i++)
       {
           int a,b;
           LL c;

           scanf("%s",sa);
           if(*sa=='!')
           {
               scanf("%d%d%lld",&a,&b,&c);
               Unio(a,b,c);
           }
           else
           {
               scanf("%d%d",&a,&b);
               int fa=Find(a),fb=Find(b);
               if(fa!=fb)
                    printf("UNKNOWN\n");
               else
                    printf("%lld\n",va[a]-va[b]);
           }

       }
   }
    return 0;
}

I uva live 6190 - Beautiful
Spacing

题目意思:

把已知长度的n个单词,放到宽度为w的格子中,要求单词的顺序不能变,且每行的开头格子和结尾格子必须有单词,两个单词中间至少有一个空格,求单词之间空格数的最大值最小。

解题思路:

二分+思维

二分答案,判断答案是否合理。dp[i]表示第i个结尾是否可行,对每个可行,推出后面的是否可行。

代码:

//#include<CSpreadSheet.h>

#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#include<cmath>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

#define Maxn 51000

bool dp[Maxn];
int n,w;
LL sum[Maxn];

bool iscan(int m)
{
    if(sum[n]+n-1<=w)
        return true;

    memset(dp,0,sizeof(dp));
    dp[0]=1;
    int la=0;

    for(int i=0;i<=n-2;i++)
    {
        if(!dp[i])
            continue;
        for(int j=max(i+1,la+1);j<=n;j++)
        {
            if(sum[j]-sum[i]+j-i-1>w) //最小的不行
                break;
            if(sum[j]-sum[i]+(j-i-1)*m<w) //最大要超过才能可行
                continue;
            dp[j]=true;
            la=j;
            if(sum[n]-sum[j]+n-j-1<=w)
                return true;
        }
    }
    return false;
}
int main()
{
    //freopen("in.txt","r",stdin);
   //freopen("out.txt","w",stdout);
   while(scanf("%d%d",&w,&n)&&w+n)
   {
       sum[0]=0;
       for(int i=1;i<=n;i++)
       {
           LL temp;
           scanf("%lld",&temp);
           sum[i]=sum[i-1]+temp;
       }
       int l=1,r=w,m,ans;

       while(l<=r)
       {
           m=(l+r)>>1;
           if(iscan(m))
           {
               ans=m;
               r=m-1;
           }
           else
                l=m+1;
       }
       printf("%d\n",ans);
   }
    return 0;
}
时间: 2024-08-08 21:21:18

[Regionals 2012 :: Asia - Tokyo ]的相关文章

Regionals 2015 &gt;&gt; Asia - Tehran &gt;&gt; 7530 - Cafebazaar【二分图最佳匹配】【KM】【最大费用流】

Regionals 2015 >> Asia - Tehran >> 7530 - Cafebazaar 题目链接:7530 题目大意:一个公司有n个开发者,有m个APP可开发.其中一些开发者必选,一些APP必选.已知每个开发者开发每个APP的收益,求最大收益.(每个开发者最多开发一个APP,每个APP最多一个人开发) 题目思路: 解法一:二分图最佳匹配(KM算法) 增加一些虚开发者和虚app,非必要app可以被虚开发者开发,收益为0,反过来非必要开发者可以开发虚app,收益为0.

Regionals 2013 Asia - Daejeon (部分题目题解)

题目链接:Regionals 2013 Asia - Daejeon 6500 Boxes 题意:将箱子(矩阵的1)全移动到矩阵的底部需要几步 思路:按列从下到上统计.(n,m)的矩阵,移动一个箱子(x,y),如果有c个箱子在底部,那么移动该箱子的步数是(n-x-c-1). AC代码: #include <stdio.h> #include <string.h> int mp[110][110]; int main() { int t; int i,j,n,m; scanf(&qu

Regionals 2014 Asia - Dhaka J 组合数学

解题思路:给你p个数,和每个数的个数,问你怎么安排使得每个位置上的最长单峰子序列的和最长. 解题思路:显然按顺序方是最大的. 解题代码: 1 // File Name: j.cpp 2 // Author: darkdream 3 // Created Time: 2015年04月04日 星期六 15时35分41秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9

Regionals 2012 :: HangZhou

题目传送门排行榜 一个人做了12年北大出的题,自己还是太弱了,图论的知识忘光光,最小生成树裸题写不来,Dijkstra TLE不知道用SPFA. 简单几何(点到线段的距离) + 三分 B Stealing a Cake 题意:圆外一个点先到圆再到矩形的最短距离. 分析:由于圆在[0, PI]和[PI, PI*2]上是单峰函数,用三分求极值,应该在[0,PI*2]上也算单峰函数吧. /************************************************ * Author

Regionals 2014 Asia - Dhaka H 暴力

题意:将区间分成四分,使得每个区间内的个数比较平均. 解题思路:暴力 解题代码: 1 // File Name: h.cpp 2 // Author: darkdream 3 // Created Time: 2015年04月04日 星期六 14时17分50秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #in

Regionals 2014 Asia - Dhaka A 映射

题意:给你一个字符串和字符转换规则,问你装换后的字符串的样子. 解题思路:vector 模拟映射 解题代码: 1 // File Name: a.cpp 2 // Author: darkdream 3 // Created Time: 2015年04月04日 星期六 13时39分13秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<de

Regionals 2015 &gt;&gt; Asia - Tehran &gt;&gt; 7527 - Funfair【贪心】【dp】

7527 - Funfair 题目链接:7527 题目大意:玩一个闯关游戏,初始为x元,总共有n关,自己选择k关,以及过关顺序.过第i关的时候,赢得概率为pi,赢了之后可获得ai元,输了的话,则输去li * x的钱.问如何选择关以及闯关顺序使得最后的金钱数期望最大. 题目思路:首先,需要将关排序,这样可以保证第i+1关一定在i关之后过,然后进行dp,第i关取或者不取. 排序方式: 我们可以知道,过第i关的时候 赢: (Ai + x) * Pi 输: (1 - Pi)(1 - Li) * x 相加

Regionals 2012 :: Chengdu

题目连接 排行榜 A和I都是签到题 按位BFS K Yet Another Multiple Problem 题意:给一些可以用的数字,求最小的数,它由特定的数字组成且是n的倍数 分析:暴力枚举不可行,因为数字可能非常大.考虑到大数取模为0,BFS每一层即数位,递归输出路径. #include <bits/stdc++.h> const int N = 1e4 + 5; bool no[10]; std::pair<int, int> pre[N]; int dir[10]; bo

2012-2013 ACM-ICPC, Asia Tokyo Regional Contest

https://codeforces.com/gym/101412 C - One-Dimensional Cellular Automaton 签到题,就是直接矩阵快速幂,一开始用longlong然后到处取模导致T了一发,卡常之后才过. 测出来了,取模大概是11倍常数,鉴于大概元素的范围是2^16次方,所以认为取模是近似一个log是可以的,毕竟本质是移位和乘法和加法神奇的编译器除法优化.就算乘法也是并行的,那也是几倍常数,而且假如不开O2就直接是除法和减法,这就完蛋了. 所以说矩阵的模板要设置