codeforces#324(div2)

codeforces#324(div2) 

A题:水题。没注意10的时候特判WA了一次。

#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a;i<=b;i++)

using namespace std;

const int maxn=1000100;
const int INF=(1<<29);

int n,t;

int main()
{
    while(cin>>n>>t){
        if(t==10){
            if(n==1){
                puts("-1");
                continue;
            }
            REP(i,1,n-1) printf("1");
            puts("0");
        }
        else{
            REP(i,1,n) printf("%d",t);
            puts("");
        }
    }
    return 0;
}
View Code

B题:水题。没注意取模的时候负数WA了一次。

#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a;i<=b;i++)

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=(1<<29);
const ll p=1e9+7;

int n;
ll x3[maxn],x7[maxn];

int main()
{
    x3[0]=x7[0]=1;
    REP(i,1,maxn-1) x3[i]=(x3[i-1]*3)%p,x7[i]=(x7[i-1]*7)%p;
    while(cin>>n){
        printf("%I64d\n",(x3[n*3]+7*p-x7[n])%p);
    }
    return 0;
}
View Code

D题:把一个奇数分解成三个质数的和。先找最接近n的尽可能大的质数a(因为质数频率很高,所以复杂度不会高),然后n-a为偶数,由歌德巴赫猜想,任何一个偶数可以分解成两个质数的和,n-a很小,直接暴力就行了。判大素数可以分解质因数,看质因子个数是否为1。

#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=10001000;
const int INF=(1<<29);

ll n;
vector<int> prime;
bool isprime[maxn];

void getPrime()
{
    memset(isprime,1,sizeof(isprime));
    isprime[1]=0;
    REP(i,2,maxn-1){
        if(!isprime[i]) continue;
        for(int j=i+i;j<maxn;j+=i){
            isprime[j]=0;
        }
    }
    REP(i,1,maxn-1) if(isprime[i]) prime.push_back(i);
}

bool IsPrime(ll n)
{
    int cnt=0;
    ll t;
    for(int i=0;i<prime.size();i++){
        t=prime[i];
        if(t*t>=n) break;
        while(n%t==0) n/=t,cnt++;
    }
    while(n%t==0) n/=t,cnt++;
    if(n!=1) cnt++;
    return cnt==1;
}

int main()
{
    getPrime();
    while(cin>>n){
        ll p;
        for(p=n;;p--){
            if(IsPrime(p)) break;
        }
        ll a=p;
        n-=p;
        if(n==0){
            printf("1\n%I64d\n",a);continue;
        }
        if(IsPrime(n)){
            printf("2\n%I64d %I64d\n",a,n);continue;
        }
        ll b,c;
        for(b=2;b<n-1;b++){
            c=n-b;
            if(IsPrime(b)&&IsPrime(c)){
                break;
            }
        }
        printf("3\n%I64d %I64d %I64d\n",a,b,c);
    }
    return 0;
}
View Code

这场C题题意理解错实在可惜,,,C题是说相同位置的不同字符,我理解成了把所有的字符拿出来去掉都有的字符剩下的不同字符,然后浪费了一个小时写C。。。。还好过了D,避免掉分。。

不过A题没注意测边缘数据,B题没注意负数取模,D题没过样例就交确实是不应该。。。话说回来,如果C不理解错题意,应该可以在40min左右过,D题可以在1h左右过,这样又一个小时4题,就重回1700了。。。不过这不是重点,重点是补完这场的C和E然后滚回实验室刷紫书。。。队友都刷到第7章了。。

 

补上C题,看清题意后一分钟秒出思路,10min 1A,这水题。。。。。。。[吐槽][吐槽][吐槽]。。。。

#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=(1<<29);

int n,t;
char s1[maxn],s2[maxn],s3[maxn];
int f[maxn];

int main()
{
    while(cin>>n>>t>>s1>>s2){
        memset(s3,'#',sizeof(s3));
        s3[n]='\0';
        int k=n-t;
        REP(i,0,n-1){
            if(k&&s1[i]==s2[i]){
                s3[i]=s1[i];k--;
            }
        }
        if(k==0){
            REP(i,0,n-1){
                if(s3[i]=='#'){
                    REP(j,'a','z'){
                        if(j!=s1[i]&&j!=s2[i]){
                            s3[i]=j;break;
                        }
                    }
                }
            }
            puts(s3);
        }
        else{
            if(t<k) puts("-1");
            else{
                int x=k,y=k;
                REP(i,0,n-1){
                    if(x&&s3[i]=='#'){
                        s3[i]=s1[i];x--;
                    }
                }
                REP(i,0,n-1){
                    if(y&&s3[i]=='#'){
                        s3[i]=s2[i];y--;
                    }
                }
                REP(i,0,n-1){
                    if(s3[i]=='#'){
                        REP(j,'a','z'){
                            if(j!=s1[i]&&j!=s2[i]){
                                s3[i]=j;break;
                            }
                        }
                    }
                }
                puts(s3);
            }
        }
    }
    return 0;
}
View Code

错失了一次涨分的机会。。。。不服不服,前四题我都可以秒过,就是题意理解错,浪费很多时间。这两场掉的rating下一场打回来!

E题:

这题是个贪心,yy题,虽然代码实现简单,但感觉|i-j|的最小代价交换还是很常见的,而且第一次见的话想yy对贪心的方向还是有难度的,所以还是得另写一个题解。

#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=(1<<29);

int n;
int p[maxn],s[maxn];
int id[maxn];
int cost;
struct Node
{
    int x,y;
};
vector<Node> ans;

int solve(int *a,int n)
{
    if(n==1) return 0;
    int x,y;
    REP(i,1,n){
        if(a[i]==n){
            x=i;break;
        }
    }
    int cost=0;
    REP(i,x+1,n){
        if(a[i]<=x){
            ans.push_back({x,i});
            swap(a[x],a[i]);
            cost+=abs(x-i);
            x=i;
        }
    }
    return cost+solve(a,n-1);
}

int main()
{
    while(cin>>n){
        ans.clear();
        REP(i,1,n) scanf("%d",&p[i]);
        REP(i,1,n) scanf("%d",&s[i]),id[s[i]]=i;
        REP(i,1,n) p[i]=id[p[i]];
        //REP(i,1,n) cout<<p[i]<<" ";cout<<endl;
        cost=solve(p,n);
        printf("%d\n%d\n",cost,(int)ans.size());
        for(int i=0;i<ans.size();i++) printf("%d %d\n",ans[i].x,ans[i].y);
    }
    return 0;
}
View Code

 

第二次在补题的时候AK了div2,上次的E是一个线段树维护字符串哈希,这次是有点难度的贪心题。什么时候能真正AK一次div2啊啊啊。。。话说回来,C和E已补完,是时候滚回实验室刷紫书了。。。

 

posted @ 2015-10-07 14:27  __560  阅读(271)  评论(0编辑  收藏  举报