Codeforces Round #175 (Div. 2) && #183 (Div. 2)

题目:Codeforces Round #175 (Div. 2)

Slightly Decreasing Permutations

求 : n的全排列,满足有k组相邻的数字满足p(i)>p(i+1)

思路:先逆序输出最后k个数字,然后正序输出剩下的,这种情况满足。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;
int a[100001];
int main()
{
    int n,k;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)
        a[i]=i;
    for(int i=n;i>=n-k+1;i--)
        printf("%d ",a[i]);
    for(int i=1;i<n-k;i++)
        printf("%d ",a[i]);
    printf("%d\n",n-k);
    return 0;
}


Find Marble

求:从 s 到 t ,中间至少需要多少次。

思路:从 s 出发,如果回到刚才走过的点,就进入死循环了,如果到达 t ,就输出长度 ,可以通过数组标记看是否进入死循环,我是判断这个长度超过n的时候break

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;
int a[100001];
int main()
{
    int n,s,t;
    scanf("%d%d%d",&n,&s,&t);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    if(s==t)
    {
        printf("0\n");
        return 0;
    }
    int ans=0;
    int tag=1;
    while(s!=t)
    {
        ans++;
        if(s==a[s])
        {
            tag=0;
            break;
        }
        s=a[s];
        if(ans>100000)
        {
            tag=0;
            break;
        }
    }
    if(!tag)
        printf("-1\n");
    else
        printf("%d\n",ans);
    return 0;
}

C: Building Permutation

求:由给定的一串数字,变成n的全排列,所需要加或减的数字总和

思路:直接sort后求与a[i]=i的排列的差的绝对值之和

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;
int a[300010];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    long long ans=0;
    sort(a+1,a+n+1);
    for(int i=1;i<=n;i++)
        ans+=abs(a[i]-i);
    printf("%I64d\n",ans);
    return 0;
}

D : Permutation Sum

求:两个全排列之和也是一个全排列的方案数

思路:一共16个数字,打表。。。。发现n是偶数时,结果是0,用了一个 next_permutation 打表,打到 n=11花了好久,估计打到n=13 就是几百倍的时间,然后n=15时,就基本上打不出来了,吭啊。

网上有对半搜索的 http://www.cnblogs.com/chenhuan001/archive/2013/04/15/3022476.html n=15的那组几十秒就打出来了,膜拜

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;
#define mod 1000000007
int main()
{
    int a[17]={0,1,0,18,0,1800,0,670320,0,734832000,0,890786230,0,695720788,0,150347555,0};
    int n;
    scanf("%d",&n);
    printf("%d\n",a[n]);
    return 0;
}

 E : Positions in Permutations

思路: DP ? 

不会 



题目:Codeforces Round #183 (Div. 2)

A :Pythagorean Theorem II

思路:暴力

尼玛,开始做的时候想复杂了,记着之前的一个结论,a和b中至少有一个数字是3的倍数,然后就想复杂了,改来改去,还是改成水过了 

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <cmath>
using namespace std;
bool is_ok(int n)
{
    int cnt=(int)sqrt(n);
    cnt*=cnt;
    if(cnt==n)
        return 1;
    return 0;
}
int main()
{
    int n;
    scanf("%d",&n);
    int ans=0;
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)
        {
            if(i*i+j*j>n*n)
                break;
            if(is_ok(i*i+j*j))
                ans++;
        }
        printf("%d\n",ans);
        return 0;
}

B: Calendar

思路:开始想用用java水过,结果发现第二组数据就跪了,这不科学啊。

实在没办法改用c++暴力了

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
using namespace std;
int month[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};
bool is_leap(int n)
{
    if(n%4==0)
    {
        if(n%100==0)
        {
            if(n%400==0)
                return 1;
            return 0;
        }
        return 1;
    }
    return 0;
}
int main()
{
    int ya,yb,ma,mb,da,db;
    scanf("%d:%d:%d",&ya,&ma,&da);
    scanf("%d:%d:%d",&yb,&mb,&db);
    int ans=0;
    if(ya>yb||(ya==yb&&ma>mb)||(ya==yb&&ma==mb&&da>db))
    {
        swap(ya,yb);
        swap(ma,mb);
        swap(da,db);
    }
    while(ya!=yb||ma!=mb||da!=db)
    {
        ans++;
        da++;
        if(is_leap(ya))
            month[2]=29;
        else
            month[2]=28;
        if(da>month[ma])
        {
            da%=month[ma];
            ma++;
        }
        if(ma>12)
        {
            ma%=12;
            ya++;
        }
    }
    printf("%d\n",ans);
    return 0;
}

比赛之后还是不甘心java为什么第二组数据我电脑里运行的没问题,提交之后就wa了,郁闷了好久  = =

看别人用 java 过的代码 ,貌似就比我多一行语句    ft.setTimeZone(TimeZone.getTimeZone("UTC"));

唉  这个是因为时区问题导致WA的 ? 尼玛

= =  再也不用 java 装逼了  (上次写一个java做题TLE) 一用就跪  这不科学啊

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
import java.util.TimeZone;

public class a{
 public static long getQuot(String time1, String time2){
  long quot = 0;
  SimpleDateFormat ft = new SimpleDateFormat("yyyy:MM:dd");
  ft.setTimeZone(TimeZone.getTimeZone("UTC"));
  try {
   Date date1 = ft.parse( time1 );
   Date date2 = ft.parse( time2 );
   quot = date1.getTime() - date2.getTime();
   quot = quot / (1000 * 60 * 60 * 24);
  } catch (ParseException e) {
   e.printStackTrace();
  }
  return quot;
 }
 public static void main(String[] args) throws Exception {
    Scanner r = new Scanner(System.in);
  String date1 = r.nextLine();
  String date2 = r.nextLine();
  long day = getQuot(date2,date1);
  System.out.println(Math.abs(day));
 }
}

C: Lucky Permutation Triple

求:两个全排列对应位置的和产生一个新的全排列

直接输出0~n-1 和 0~n-1

然后第三行输出 和对n取余的结果

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
    int n;
    scanf("%d",&n);
    if(n%2==0)
        printf("-1\n");
    else
    {
        for(int i=0;i<n-1;i++)
            printf("%d ",i);
        printf("%d\n",n-1);
        for(int i=0;i<n-1;i++)
            printf("%d ",i);
        printf("%d\n",n-1);
        for(int i=0;i<n-1;i++)
            printf("%d ",i*2%n);
        printf("%d\n",(2*n-2)%n);
    }
    return 0;

}

D: Rectangle Puzzle II

求:满足比列是 a:b的矩形内含某个点

思路:求gcd将比例简化之后,求出矩形的大小,然后移动 

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdio>
using namespace std;
int gcd(int a,int b)
{
    if(b==0)
        return a;
    return gcd(b,a%b);
}
int main()
{
    int m,n,x,y,a,b;
    scanf("%d%d%d%d%d%d",&m,&n,&x,&y,&a,&b);
    int ggcd=gcd(a,b);
    a/=ggcd;
    b/=ggcd;
    int tmp=min(m/a,n/b);
    int width=tmp*a;
    int length=tmp*b;
    int x1,x2,y1,y2;
    if(width&1)
    {
        x1=x-width/2-1;
        x2=x1+width;
    }
    else
    {
        x1=x-width/2;
        x2=x1+width;
    }
    if(length&1)
    {
        y1=y-length/2-1;
        y2=y1+length;
    }
    else
    {
        y1=y-length/2;
        y2=y+length/2;
    }
    if(x1<0)
    {
        x2-=x1;
        x1=0;
    }
    if(y1<0)
    {
        y2-=y1;
        y1=0;
    }
    if(x2>m)
    {
        x1-=(x2-m);
        x2=m;
    }
    if(y2>n)
    {
        y1-=(y2-n);
        y2=n;
    }
    printf("%d %d %d %d\n",x1,y1,x2,y2);
    return 0;
}


E: Minimum Modular

求:n个数,在能去掉k个数的情况下,求最小的mod,使得所有的数字能够刚好取余编号

不会


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值