Fork me on GitHub

UESTC-第五届ACM趣味程序设计竞赛第四场(正式赛)--不完全解题报告

 比赛链接: http://acm.uestc.edu.cn/contest.php?cid=230

A.Police And The Thief  ---UESTC 1913

简单博弈,先假设在警察先走的情况下分析,小偷先走的结果在其基础上取反面即可。我是这样做的,随便假设小偷在一个点,在这个点的四周都是必败态(警察抓不到),然后一步可以到达必败态的点都是必胜态,一次推向远处,容易发现规律: 当abs(xp-xt)%2==abs(yp-yt)%2时都是必败态,否则是必败态,这是结果已经得出。

两个特殊情况:  1.开始时两人在同一点,算YES。

                      2.格子为n*1或1*m形式,必然可以抓到,算YES。

代码:

                        #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <time.h>
#include <queue>
#include <cctype>
#include <numeric>
#include <cstdlib>
#include <iomanip>
#include <sstream>
#define mod 1000000007
#define INT 2147483647
#define pi acos(-1.0)
#define eps 1e-3
#define lll __int64
#define ll long long
using namespace std;
#define N 200005

int main()
{
    int t,i;
    int n,m;
    int xp,yp,xt,yt;
    int flag;
    char ss[10];
    scanf("%d",&t);
    while(t--)
    {
        flag = 1;
        scanf("%d%d",&n,&m);
        scanf("%d%d%d%d",&xp,&yp,&xt,&yt);
        scanf("%s",ss);
        if((n == 1 || m == 1)||(xp == xt && yp == yt))
        {
            cout<<"YES\n";
            continue;
        }
        int ka = abs(yp-yt);
        int kb = abs(xp-xt);
        if(ka%2 == kb%2)
        {
            flag = 0;
        }
        
        if(ss[0] == 'p')
        {
            if(flag)
                cout<<"YES"<<endl;
            else
                cout<<"NO"<<endl;
        }
        else
        {
            if(flag)
                cout<<"NO"<<endl;
            else
                cout<<"YES"<<endl;
        }
    }
    return 0;
}

                     
View Code

 

B.Similar strings ---UESTC 1916

我的思路如下:从第一个字符串(后文称a)中第一个字符扫起,遇见一个字母(如'A'),如果没有标记,则标记为第二个字符串(后文称b)的该位字母,然后在循环里面扫一遍a,如果有等于这个字母的,而b对应的不相等,或者,不等于这个字母而b对应的又相等了,则tag = 0,说明不是,否则就是。这里最多26个字母,虽然是二重循环,但是不会超时。

代码:

                        #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <time.h>
#include <queue>
#include <cctype>
#include <numeric>
#include <cstdlib>
#include <iomanip>
#include <sstream>
#define mod 1000000007
#define INT 2147483647
#define pi acos(-1.0)
#define eps 1e-3
#define lll __int64
#define ll long long
using namespace std;
#define N 200005

char flag[27];

string tostring(char a)
{
    string tmp = "";
    tmp +=a;
    return tmp;
}

int main()
{
    string aa,bb;
    int t,i;
    scanf("%d",&t);
    while(t--)
    {
        memset(flag,0,sizeof(flag));
        cin>>aa;
        cin>>bb;
        int j;
        if(aa.length()!=bb.length())
        {
            cout<<"NO"<<endl;
            continue;
        }
        int tag = 1;
        for(i=0;i<aa.length();i++)
        {
            if(!flag[aa[i]-'A'])
            {
                flag[aa[i]-'A'] = bb[i];
                for(j = i+1;j<aa.length();j++)
                {
                    if(aa[i] == aa[j])
                    {
                        if(bb[i] != bb[j])
                        {
                            tag = 0;
                            break;
                        }
                    }
                    else 
                    {
                        if(bb[i] == bb[j])
                        {
                            tag = 0;
                            break;
                        }
                    }
                }
            }
        }

        if(tag)
            cout<<"YES\n";
        else
            cout<<"NO"<<endl;
    }
    return 0;
}
                     
View Code

 

 

C.The Game of Little P  ---UESTC 1915

简单推公式题,公式很简单: ans = m*(m+1)*(2*m+1)/6 * n/(m+1) + modi*(modi+1)*(2*modi+1)/6 .  【modi = n%(m+1)】 难就难在计算出这个结果,又因为有取模的性质:(A * B) mod C = ((A mod C) * (B mod C)) mod C, 但是除法并不满足,所以要看m*(m+1)*(2*m+1)这个里面有没有可以被6整除的一个或两个数,先把6除掉,然后再用取模的性质解决。

 

代码:

                        #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <time.h>
#include <queue>
#include <cctype>
#include <numeric>
#include <cstdlib>
#include <iomanip>
#include <sstream>
#define mod 1000000007
#define INT 2147483647
#define pi acos(-1.0)
#define eps 1e-3
#define lll __int64
#define ll long long
using namespace std;
#define Mod 1000000007LL

long long calc(long long m)
{
    long long ka,res;
    long long a = m*(m+1);
    long long b = 2*m+1;
    long long c = m*(2*m+1);
    long long d = (m+1)*(2*m+1);
        if(m%6==0) //
        {
            ka = m/6;
            ka = ((ka%Mod)*((m+1)%Mod))%Mod;
            res = ((ka%Mod)*(b%Mod))%Mod;
        }
        else if((m+1)%6==0) //
        {
            ka = (m+1)/6;
            ka%=Mod;
            res = ((m%Mod)*ka)%Mod;
            res = (res*(b%Mod))%Mod;
        }
        else if(b%6==0) //
        {
            b/=6;
            res = ((a%Mod)*(b%Mod))%Mod;
        }
        else if(a%6==0)   //deux
        {
            a/=6;
            res = ((a%Mod)*(b%Mod))%Mod;
        }
        else if(c%6==0)
        {
            ka = c/6;
            res = ((ka%Mod)*((m+1)%Mod))%Mod;
        }
        else if(d%6==0)
        {
            ka = d/6;
            res = ((ka%Mod)*(m%Mod))%Mod;
        }
        return res%Mod;
}

int main()
{
    long long int n,m;
    int modi,i;
    int t;
    scanf("%d",&t);
    while(t--)
    {
        long long res;
        scanf("%lld%lld",&n,&m);
        modi = n%(m+1);
        res = calc(m);
        res = (res*(n/(m+1)))%Mod;
        long long cas = calc(modi);
        long long ans = (res+cas)%Mod;
        cout<<ans<<endl;
    }
    return 0;
}

                     
View Code

 

D.Trees  ----UESTC 1918

    这题开始没想通,后来看了别人的解法才知道原来是多么弱的题,用贪心就行了,因为最少也应该满足1 2 3...3 2 1形式,先做一个假设数组就是1 2 3...3 2 1,然后再使输入的tree数组减去assume数组,得出差异,取差出现最多的一些数让他们不动,其余的都得动,当然,如果差小于0,那更是必须得动,此时动的树的数目一定是最小的。

 

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <time.h>
#include <queue>
#include <cctype>
#include <numeric>
#include <cstdlib>
#include <iomanip>
#include <sstream>
#define Mod 1000000007
#define INT 2147483647
#define pi acos(-1.0)
#define eps 1e-3
#define lll __int64
#define ll long long
using namespace std;

int tree[100005];
int assume[100005];
int dif[100005];
int flag[100005];

int main()
{
    int n,i,j;
    int t;
    scanf("%d",&t);
    while(t--)
    {
        memset(flag,0,sizeof(flag));
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            scanf("%d",&tree[i]);
        }
        int mid = (n+1)/2;
        for(i=1;i<=mid;i++)
        {
            assume[i] = i;
        }
        for(i=mid+1;i<=n;i++)
        {
            assume[i] = assume[n-i+1];
        }
        int maxdif = -1000000;
        int diftag;
        for(i=1;i<=n;i++)
        {
            dif[i] = tree[i]-assume[i];
            if(dif[i]>=0)
            {
                flag[dif[i]]++;
                if(flag[dif[i]]>maxdif)
                {
                    maxdif = flag[dif[i]];
                    diftag = dif[i];
                }
            }
        }
        int cnt = 0;
        for(i=1;i<=n;i++)
        {
            if(dif[i]!=diftag)
            {
                cnt++;
            }
        }
        cout<<cnt<<endl;
    }
    return 0;
}
                     
View Code

 

其余的还没做出来,等我后面更新。。有错误欢迎指正。

posted @ 2013-12-22 00:52  whatbeg  阅读(811)  评论(0编辑  收藏  举报