cf_292 Div.2

源地址:http://codeforces.com/contest/515

A:输入三个数a,b,n.问能否用n步从(0,0)点走到(a,b)点,移动方向为上下左右。

很明显,先求出到a,b至少移动几步,如果用n步都不能到达(a,b),那么显然不能。。如果n大于等于走到(a,b)的最小步数且(n-最小步数)为偶数时(即可以反复在用一个地方走动)时能够到达。

#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<time.h>
#include<queue>
#include<stack>
#include<iterator>
#include<math.h>
#include<stdlib.h>
#include<limits.h>
#include<map>
//#define ONLINE_JUDGE
#define eps 1e-8
#define INF 0x7fffffff
#define FOR(i,a) for((i)=0;i<(a);(i)++)
#define MEM(a) (memset((a),0,sizeof(a)))
#define sfs(a) scanf("%s",a)
#define sf(a) scanf("%d",&a)
#define sfI(a) scanf("%I64d",&a)
#define pf(a) printf("%d\n",a)
#define pfI(a) printf("%I64d\n",a)
#define pfs(a) printf("%s\n",a)
#define sfd(a,b) scanf("%d%d",&a,&b)
#define sft(a,b,c)scanf("%d%d%d",&a,&b,&c)
#define for1(i,a,b) for(int i=(a);i<b;i++)
#define for2(i,a,b) for(int i=(a);i<=b;i++)
#define for3(i,a,b)for(int i=(b);i>=a;i--)
#define MEM1(a) memset(a,0,sizeof(a))
#define MEM2(a) memset(a,-1,sizeof(a))
const double PI=acos(-1.0);
template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
template<class T> inline T Min(T a,T b){return a<b?a:b;}
template<class T> inline T Max(T a,T b){return a>b?a:b;}
using namespace std;
#define ll __int64
int n,m;
#define Mod 10
#define N 100010
ll Abs(ll x){
    return x>0?x:-x;
}
int main(){
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
//  freopen("out.txt","w",stdout);
#endif
    ll a,b,s;
    while(scanf("%I64d%I64d%I64d",&a,&b,&s)!=EOF){
        ll dif = Abs(a)+Abs(b);
        s -= dif;
        if(s>=0 && (s%2==0)){
            printf("Yes\n");
        }else
            printf("No\n");
    }
return 0;
}
B:题意就是有n个男孩和m个女孩,n个男孩中状态好的被标志为1,状态不好的为0,女孩亦如此。从头开始,每一天选择一对男女孩,即在i<min(n,m)时这对男女孩为第i个男孩和第i个女孩配对,如果其中有一个状态好的,那么两个人状态都会变好,即都会变为1。当i>min(n,m)时,那么选择完的那一方将会从头重新开始按顺序选择,即(i+1)%n和(i+1)%m进行配对。问最后能否使得所有人的状态都变好。

模拟题,我们发现每当配对至lcm(n,m)次时,那么男孩和女孩的配对方式会和刚开始的一样,等于循环了一遍。所以我们只要进行lcm(n,m)次配对就可以了,再对每个人状态检查一遍即可。刚开始我没细想,直接将每次配对都循环1000010次,这样得出结果也是一样的,因为n,m都比较小。

#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<time.h>
#include<queue>
#include<stack>
#include<iterator>
#include<math.h>
#include<stdlib.h>
#include<limits.h>
#include<map>
//#define ONLINE_JUDGE
#define eps 1e-8
#define INF 0x7fffffff
#define FOR(i,a) for((i)=0;i<(a);(i)++)
#define MEM(a) (memset((a),0,sizeof(a)))
#define sfs(a) scanf("%s",a)
#define sf(a) scanf("%d",&a)
#define sfI(a) scanf("%I64d",&a)
#define pf(a) printf("%d\n",a)
#define pfI(a) printf("%I64d\n",a)
#define pfs(a) printf("%s\n",a)
#define sfd(a,b) scanf("%d%d",&a,&b)
#define sft(a,b,c)scanf("%d%d%d",&a,&b,&c)
#define for1(i,a,b) for(int i=(a);i<b;i++)
#define for2(i,a,b) for(int i=(a);i<=b;i++)
#define for3(i,a,b)for(int i=(b);i>=a;i--)
#define MEM1(a) memset(a,0,sizeof(a))
#define MEM2(a) memset(a,-1,sizeof(a))
const double PI=acos(-1.0);
template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
template<class T> inline T Min(T a,T b){return a<b?a:b;}
template<class T> inline T Max(T a,T b){return a>b?a:b;}
using namespace std;
#define ll __int64
int n,m;
#define Mod 10
#define N 110
#define M 1000010
int by[N];
int gr[N];
int main(){
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
//  freopen("out.txt","w",stdout);
#endif
    while(sfd(n,m)!=EOF){
        MEM1(by);
        MEM1(gr);
        int x,y,tmp;
        sf(x);
        for(int i=0;i<x;i++){
            sf(tmp);
            by[tmp] = 1;
        }
        sf(y);
        for(int i=0;i<y;i++){
            sf(tmp);
            gr[tmp] = 1;
        }
        int p1=0,p2=0;
        int ct=0;
        while(ct<M){
            by[p1] = gr[p2] = (by[p1]|gr[p2]);
            p1 = (p1+1)%n;
            p2 = (p2+1)%m;
            ct++;
        }
        int flag=1;
        for(int i=0;i<n;i++)
            if(!by[i])
                flag=0;
        for(int i=0;i<m;i++)
            if(!gr[i])
                flag=0;
        if(flag)
            printf("Yes\n");
        else
            printf("No\n");
    }
return 0;
}
C:给你一个x,求找到一个不含0,1数字的a,使得函数F(x)=F(a)

F(1234)=1!*2!*3!*4!

这道题目我的方法比较笨,就是把数字拿来分解,对于x中的每一个数字,如果它是素数,那么就把它写到a中的某一位,如果是合数,那么就把它进行分解,分解为多个素数的乘积,最后输出。

但是其实一共就10个数字,我们把每个数字的分解形式找出来就行,比如F(1234)=F(33222),我们可以看出,这里的4!被分解为3!2!2!,同理9!可以被分为7!2!3!3!

#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<time.h>
#include<queue>
#include<stack>
#include<iterator>
#include<math.h>
#include<stdlib.h>
#include<limits.h>
#include<map>
//#define ONLINE_JUDGE
#define eps 1e-8
#define INF 0x7fffffff
#define FOR(i,a) for((i)=0;i<(a);(i)++)
#define MEM(a) (memset((a),0,sizeof(a)))
#define sfs(a) scanf("%s",a)
#define sf(a) scanf("%d",&a)
#define sfI(a) scanf("%I64d",&a)
#define pf(a) printf("%d\n",a)
#define pfI(a) printf("%I64d\n",a)
#define pfs(a) printf("%s\n",a)
#define sfd(a,b) scanf("%d%d",&a,&b)
#define sft(a,b,c)scanf("%d%d%d",&a,&b,&c)
#define for1(i,a,b) for(int i=(a);i<b;i++)
#define for2(i,a,b) for(int i=(a);i<=b;i++)
#define for3(i,a,b)for(int i=(b);i>=a;i--)
#define MEM1(a) memset(a,0,sizeof(a))
#define MEM2(a) memset(a,-1,sizeof(a))
const double PI=acos(-1.0);
template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
template<class T> inline T Min(T a,T b){return a<b?a:b;}
template<class T> inline T Max(T a,T b){return a>b?a:b;}
using namespace std;
#define ll __int64
int n,m;
#define Mod 10
#define N 110
#define M 1000010
char ch[20];
int ct[15];
int prm[20];
int res[110];
int k;
void Init(){
    k=0;
    prm[k++] = 2;
    prm[k++] = 3;
    prm[k++] = 5;
    prm[k++] = 7;
}
bool check(int x){
    if(x==2||x==3||x==5||x==7)
        return true;
    return false;
}
int main(){
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
//  freopen("out.txt","w",stdout);
#endif
    ll x;
    Init();
    while(sf(n)!=EOF){
            sfI(x);
            sprintf(ch,"%I64d",x);
            int len = strlen(ch);
            memset(ct,0,sizeof ct);
            for(int i=0;i<len;i++){
                for(int j=ch[i]-'0';j>=2;j--){
                    ct[j]++;
                }
            }
            int p=0;
            for(int i=9;i>1;i--){
                if(ct[i]&&check(i)){
                    for(int j=0;j<ct[i];j++){
                        res[p++] = i;
                        for(int s=i-1;s>1;s--)
                            ct[s]--;
                    }
                }
                else if(ct[i]&&!check(i)){
                    int tmp=i;
                    for(int j=0;j<k;j++){
                        if(tmp%prm[j]==0){
                            while(tmp%prm[j]==0){
                                tmp /= prm[j];
                                ct[prm[j]] += ct[i];
                            }
                        }
                    }
                }
            }
            for(int i=0;i<p;i++)
                printf("%d",res[i]);
            printf("\n");
    }
return 0;
}

简单解法:

string a[10] = {"", "", "2", "3", "223", "5", "35", "7", "2227", "7233"};<span style="white-space:pre">	</span>//0-10的分解方法

int main()
{
    int n;
    string s, ans;
    cin >> n >> s;
    for(int i = 0; i < n; ++i) ans += a[s[i]-'0'];
    sort(ans.begin(), ans.end());
    reverse(ans.begin(), ans.end());
    cout << ans << endl;

    return 0;
}

D:题意就是给你一个n*m的地图,有‘.’和‘*’两种图案,其中'.'的地方是可以放东西的,题目给的是1*2大小的东西,问是否存在且只有一种方法使得1*2的东西能够刚好把这地图填满(即没有'.')。

刚开始用了dfs,,直接超时了。。--

后来参考了下别人,用的是bfs,其实思路相当清晰。

对于一个只有一种方法的地图来说,肯定有个地方是只能放<>或者^v的,要不然如果所有地方都能够放置两种方法,那总的肯定也不至一种。

当我们每找到一个这种只能放一种图案的空地时(我们姑且称它为符合条件的空地),我们就将它入队,然后当每个这种空地出队时,我们把它和它旁边仅有的那块空地组成一个唯一的图案,再在那块“旁边的空地”上向四周找寻符合条件的空地(因为它四周的空地因为少了它以后,就很有可能会成为一块符合条件的空地),如果有符合条件的,就入队,直到队列为空。

最后我们在地图中寻找是否还残留有'.'的地方,如果有,那么说明该地图不能被1*2的东西填满。反之则反。

#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<time.h>
#include<queue>
#include<stack>
#include<iterator>
#include<math.h>
#include<stdlib.h>
#include<limits.h>
#include<map>
//#define ONLINE_JUDGE
#define eps 1e-8
#define INF 0x7fffffff
#define FOR(i,a) for((i)=0;i<(a);(i)++)
#define MEM(a) (memset((a),0,sizeof(a)))
#define sfs(a) scanf("%s",a)
#define sf(a) scanf("%d",&a)
#define sfI(a) scanf("%I64d",&a)
#define pf(a) printf("%d\n",a)
#define pfI(a) printf("%I64d\n",a)
#define pfs(a) printf("%s\n",a)
#define sfd(a,b) scanf("%d%d",&a,&b)
#define sft(a,b,c)scanf("%d%d%d",&a,&b,&c)
#define for1(i,a,b) for(int i=(a);i<b;i++)
#define for2(i,a,b) for(int i=(a);i<=b;i++)
#define for3(i,a,b)for(int i=(b);i>=a;i--)
#define MEM1(a) memset(a,0,sizeof(a))
#define MEM2(a) memset(a,-1,sizeof(a))
#define Pr(x,y) make_pair(x,y)
const double PI=acos(-1.0);
template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
template<class T> inline T Min(T a,T b){return a<b?a:b;}
template<class T> inline T Max(T a,T b){return a>b?a:b;}
using namespace std;
#define ll __int64
int n,m;
#define Mod 10
#define N 110
#define M 100010
char ch[2010][2010];
char tmp[2010][2010];
char s[5] = "<^>v";<span style="white-space:pre">	</span>//这个的顺序要和dirx和diry的相对应
int dirx[4] = {0,1,0,-1};
int diry[4] = {1,0,-1,0};
bool check(int x,int y){
    if(x>=0&&x<n&&y>=0&&y<m&&ch[x][y] == '.')
        return true;
    return false;
}
int getNum(int x,int y){<span style="white-space:pre">	</span>//判断x,y是否为符合条件的空地
    int res=0;
    for(int i=0;i<4;i++){
        int nx = x+dirx[i];
        int ny = y+diry[i];
        if(check(nx,ny))
             res++;
    }
    return res;
}
queue<pair<int,int> >q;
int main(){
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
//  freopen("out.txt","w",stdout);
#endif
    while(sfd(n,m)!=EOF){
        for(int i=0;i<n;i++)
            sfs(ch[i]);
        while(!q.empty())
            q.pop();
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(check(i,j)&&getNum(i,j)==1)
                    q.push(Pr(i,j));
            }
        }
        while(!q.empty()){
            int tmpx = q.front().first;
            int tmpy = q.front().second;
            q.pop();
            for(int i=0;i<4;i++){
                int nx = tmpx+dirx[i];
                int ny = tmpy+diry[i];
                if(check(nx,ny)){
                    ch[tmpx][tmpy] = s[i];
                    ch[nx][ny] = s[i^2];  //0&2 2&0 1&3 3&1
                    for(int j=0;j<4;j++){
                        int nxx = nx+dirx[j];
                        int nyy = ny+diry[j];
                        if(check(nxx,nyy)&&getNum(nxx,nyy)==1){
                            q.push(Pr(nxx,nyy));
                        }
                    }
                }
            }
         }
            int flag = 1;
            for(int i=0;i<n;i++)
                for(int j=0;j<m;j++){
                    if(ch[i][j] == '.')
                        flag = 0;
                }
            if(!flag)
                printf("Not unique\n");
            else{
                for(int i=0;i<n;i++)
                    printf("%s\n",ch[i]);
            }
    }
return 0;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值