A

给出边与坐标轴平行的正方形的两个点的坐标,输出另外两个点的坐标,如果不能构成正方形,输出-1。

直接枚举每一种情况就ok了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <string>
#include <vector>
#include <utility>
#define REP(i,n) for(i=0;i<(n);++i)
#define FOR(i,n) for(i=1;i<=(n);++i)
using namespace std;
typedef long long ll;
typedef vector<int> VI;
typedef pair<int,int> pii;
const int INF = 1<<30;
const double eps = 0.000001;
const int N = 100;

pii a,b,c,d;
#define x first
#define y second

int fabs(int x)
{
    return x>=0?x:-x;
}

void run()
{
    if(a.x == b.x)
    {
        int d = fabs(a.y-b.y);
        printf("%d %d %d %d\n",a.x+d,a.y,b.x+d,b.y);
    }
    else if(a.y==b.y)
    {
        int d = fabs(a.x-b.x);
        printf("%d %d %d %d\n",a.x,a.y+d,b.x,b.y+d);
    }
    else
    {
        if(fabs(a.x-b.x) != fabs(a.y-b.y))  printf("-1\n");
        else
        {
            printf("%d %d %d %d\n",a.x,b.y,b.x,a.y);
        }
    }
}

int main()
{
    while(scanf("%d%d%d%d",&a.first,&a.second,&b.first,&b.second)!=EOF)
        run ();
    return 0;
}
View Code

 

B

给出n个数字,求出这n个数字里的最大差值,以及能构成这个最大差值的有多少个对数

排序一下,看看最小的数有x个,最大的数有y个,答案就是x*y了

不过需要特判一下,如果全部元素相同的话,那么对数就是 n*(n-1)/2 了

还有注意个数可能爆int

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <string>
#include <vector>
#include <utility>
#define REP(i,n) for(i=0;i<(n);++i)
#define FOR(i,n) for(i=1;i<=(n);++i)
using namespace std;
typedef long long ll;
typedef vector<int> VI;
typedef pair<int,int> pii;
const int INF = 1<<30;
const double eps = 0.000001;
const int N = 200010;

int a[N];
int n;

ll cal(ll x)
{
    return x*(x-1)/2;
}
void run()
{
    for(int i=0;i<n;++i)    scanf("%d",&a[i]);
    sort(a,a+n);
    if(a[0]==a[n-1])
    {
        cout<<"0 "<<cal((ll)n)<<endl;
        return;
    }
    ll x = upper_bound(a,a+n,a[0]) - a;
    ll y = a + n - lower_bound(a,a+n,a[n-1]);
    cout<<a[n-1]-a[0]<<' '<<x*y<<endl;
}

int main()
{
    while(cin>>n)
        run ();
    return 0;
}
View Code

 

C

有n个学生,k个校巴,d天。问怎样安排学生们的座位,使得对于任意两个学生,不能够全部d天都是坐在同一辆车上。输出合法的方案。答案有多种解,输出其中一个就可以了

对于某个学生来说,他从第一天到第d天坐的校巴编号可以构成一个序列 a1、a2、……ad,那样合法的方案就是说,对于任意两个学生,他们的序列不能完全相同。所以k个校巴坐d天,最多的状态数就是k^d个,如果n大于这个数,则无解,否则的话就构造n个这样的序列,其实就是构造n个长度为d的k进制数

我首先判断下n是否小于k^d,不是则直接输出-1,否则就dfs构造n个这样的数字,最后输出。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <string>
#include <vector>
#include <utility>
#define REP(i,n) for(i=0;i<(n);++i)
#define FOR(i,n) for(i=1;i<=(n);++i)
using namespace std;
typedef long long ll;
typedef vector<int> VI;
typedef pair<int,int> pii;
const int INF = 1<<30;
const double eps = 0.000001;
const int N = 1010;

ll n,k,d;
int ans[N][N];
int tmp[N];
int stu;
void dfs(int cur)
{
    if(stu>n)   return;
    if(cur>d)
    {
        for(int i=1;i<=d;++i)
            ans[stu][i] = tmp[i];
        stu++;
        return;
    }
    for(int i=1;i<=k;++i)
    {
        tmp[cur]=i;
        dfs(cur+1);
        if(stu>n)   return;
    }
}

bool ok()
{
    ll kk=1;
    for(int i=1;i<=d;++i)
    {
        kk *= k;
        if(n<=kk)   return 1;
    }
    return 0;
}

void run()
{
    if(!ok())
    {
        cout<<"-1"<<endl;
        return;
    }
    stu = 1;
    dfs(1);
    for(int i=1;i<=d;++i)
    {
        for(int j=1;j<=n;++j)
            cout<<ans[j][i]<<' ';
        cout<<endl;
    }
//    cout<<"ok"<<endl;
}

int main()
{
    ios::sync_with_stdio(false);
    while(cin>>n>>k>>d)
        run ();
    return 0;
}
View Code

 

D

好困明天补

 

E

立刻想到树dp,不过TLE了,正解貌似不是树dp。等题解吧。

 posted on 2014-08-16 02:43  someblue  阅读(144)  评论(0)    收藏  举报