PAT 团体程序设计天梯赛 部分题目题解

  • L1-002 打印沙漏
  • L1-006 连续因子
  • L1-010 比较大小
  • L1-014 简单题
  • L1-018 大笨钟
  • L2-002 链表去重
  • L2-010 排座位
  • L3-002 堆栈
  • L3-006 迎风一刀斩

L1-002. 打印沙漏

本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打印

*****
 ***
  *
 ***
*****

所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递增;首尾符号数相等。

给定任意N个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉

尽可能多的符号。

模拟

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<‘ ‘; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<‘ ‘;                        cout<<a[i][m]<<endl;                         }
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch==‘-‘) f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-‘0‘; ch=getchar();}
    return x*f;
}
int main()
{
//  freopen("b.in","r",stdin);
//  freopen(".out","w",stdout);
    int n;
    char c;
    scanf("%d %c\n",&n,&c);
    int i,t;
    for(i=1,t=1;t+i*2+4<=n;i+=2,t+=(i*2)) ;

    for(int k=i;k>0;k-=2) {
        int p=(i-k)/2;
        For(j,p) putchar(‘ ‘);
        For(j,k) putchar(c);
        puts("");
    }
    for(int k=3;k<=i;k+=2) {
        int p=(i-k)/2;
        For(j,p) putchar(‘ ‘);
        For(j,k) putchar(c);
        puts("");
    }
    cout<<n-t<<endl;    

    return 0;
}

L1-006. 连续因子

一个正整数N的因子中可能存在若干连续的数字。例如630可以分解为3*5*6*7,其中5、6、7就是3个连续的数字。给定任一正整数N,要求编写程序求出最长连续因子的个数,并输出最小的连续因子序列。

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<‘ ‘; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<‘ ‘;                        cout<<a[i][m]<<endl;                         }
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch==‘-‘) f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-‘0‘; ch=getchar();}
    return x*f;
}
int main()
{
//  freopen("c.in","r",stdin);
//  freopen(".out","w",stdout);
    ll n=read();
    int an=0,q=0;
    for(ll i=2;i<=sqrt((double)n+0.5);i++) {
        if (n%i==0) {
            int p=0,t=n,j=i;
            while(t%j==0) {
                t/=j;
                p++;j++;
            }
            if (an<p) {
                an=p;
                q=i;
            }
        }
    }
    if (!an) {
        an=1; q=n;
    }
    cout<<an<<endl;
    Fork(i,q,q+an-2) {
        cout<<i<<‘*‘;
    }
    cout<<q+an-1<<endl;
    return 0;
}

L1-010. 比较大小

将输入的任意3个整数从小到大输出

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<‘ ‘; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<‘ ‘;                        cout<<a[i][m]<<endl;                         }
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch==‘-‘) f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-‘0‘; ch=getchar();}
    return x*f;
}
int main()
{
//  freopen("L110.in","r",stdin);
//  freopen(".out","w",stdout);
    int c[10];
    Rep(i,3) cin>>c[i];
    sort(c,c+3);
    printf("%d->%d->%d\n",c[0],c[1],c[2]);

    return 0;
}

L1-014. 简单题

在一行中输出事实:“This is a simple problem.”

puts一行

L1-018. 大笨钟

微博上有个自称“大笨钟V”的家伙,每天敲钟催促码农们爱惜身体早点睡觉。不过由于笨钟自己作息也不是很规律,所以敲钟并不定时。一般敲钟的点数是根据敲钟时间而定的,如果正好在某个整点敲,那么“当”数就等于那个整点数;如果过了整点,就敲下一个整点数。另外,虽然一天有24小时,钟却是只在后半天敲1~12下。例如在23:00敲钟,就是“当当当当当当当当当当当”,而到了23:01就会是“当当当当当当当当当当当当”。在午夜00:00到中午12:00期间(端点时间包括在内),笨钟是不敲的。

根据当前时间替大笨钟敲钟。

注意读题

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<‘ ‘; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<‘ ‘;                        cout<<a[i][m]<<endl;                         }
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch==‘-‘) f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-‘0‘; ch=getchar();}
    return x*f;
}
int main()
{
//  freopen("l118.in","r",stdin);
//  freopen(".out","w",stdout);
    int h,t;
    scanf("%d:%d\n",&h,&t);
    if (h<=11||(h==12&&t==0)) {
        printf("Only %02d:%02d.  Too early to Dang.",h,t);
    }
    else {
        int p=h-12;
        if (t) p++;
        For(i,p) cout<<"Dang";cout<<endl;
    }

    return 0;
}

L2-002. 链表去重

给定一个带整数键值的单链表L,本题要求你编写程序,删除那些键值的绝对值有重复的结点。即对任意键值K,只有键值或其绝对值等于K的第一个结点可以被保留。同时,所有被删除的结点必须被保存在另外一个链表中。例如:另L为21→-15→-15→-7→15,则你必须输出去重后的链表21→-15→-7、以及被删除的链表-15→15。

读题

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<‘ ‘; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<‘ ‘;                        cout<<a[i][m]<<endl;                         }
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch==‘-‘) f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-‘0‘; ch=getchar();}
    return x*f;
}
int n,ro;
int a[100000+10],ne[100000+10];
bool b[100000+10]={0};
vi v1,v2;
int Abs(int x){
    if (x<0) x=-x; return x;
}
int main()
{
//  freopen("L202.in","r",stdin);
//  freopen(".out","w",stdout);
    cin>>ro>>n;
    For(i,n) {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        a[x]=y; ne[x]=z;
    }
    for(int i=ro;i!=-1;i=ne[i]) {
        if (!b[Abs(a[i])]) v1.pb(i),b[Abs(a[i])]=1;
        else v2.pb(i);
    }
    int sz=v1.size();
    Rep(i,sz-1) {
        int p=v1[i];
        printf("%05d %d %05d\n",p,a[p],v1[i+1]);
    }
    if (sz) printf("%05d %d -1\n",v1[sz-1],a[v1[sz-1]]);

    sz=v2.size();
    Rep(i,sz-1) {
        int p=v2[i];
        printf("%05d %d %05d\n",p,a[p],v2[i+1]);
    }
    if (sz) printf("%05d %d -1\n",v2[sz-1],a[v2[sz-1]]);

    return 0;
}

L2-010. 排座位

布置宴席最微妙的事情,就是给前来参宴的各位宾客安排座位。无论如何,总不能把两个死对头排到同一张宴会桌旁!这个艰巨任务现在就交给你,对任何一对客人,请编写程序告诉主人他们是否能被安排同席。

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<‘ ‘; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<‘ ‘;                        cout<<a[i][m]<<endl;                         }
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch==‘-‘) f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-‘0‘; ch=getchar();}
    return x*f;
}
#define MAXN (100+10)
class bingchaji
{
public:
    int father[MAXN],n;
    void mem(int _n)
    {
        n=_n;
        For(i,n) father[i]=i;
    }
    int getfather(int x)
    {
        if (father[x]==x) return x;

        return father[x]=getfather(father[x]);
    }
    void unite(int x,int y)
    {
        father[x]=getfather(father[x]);
        father[y]=getfather(father[y]);
        father[father[x]]=father[father[y]];
    }
    bool same(int x,int y)
    {
        return getfather(x)==getfather(y);
    }
}S;
int f[MAXN][MAXN]={0};
int main()
{
//  freopen("L210.in","r",stdin);
//  freopen(".out","w",stdout);

    int n=read(),m=read(),k=read();
    S.mem(n);
    For(i,m) {
        int u=read(),v=read(),w=read();
        if (w==-1) f[u][v]=f[v][u]=1;
        else S.unite(u,v);
    }
    For(i,k) {
        int u=read(),v=read();
        int b1 = S.same(u,v) ,b2=f[u][v];
        if (b1&&b2) puts("OK but...");
        if (b1&&!b2) puts("No problem");
        if (!b1&&b2) puts("No way");
        if (!b1&&!b2) puts("OK");
    }   

    return 0;
}

L3-002. 堆栈

大家都知道“堆栈”是一种“先进后出”的线性结构,基本操作有“入栈”(将新元素插入栈顶)和“出栈”(将栈顶元素的值返回并从堆栈中将其删除)。现请你实现一种特殊的堆栈,它多了一种操作叫“查中值”,即返回堆栈中所有元素的中值。对于N个元素,若N是偶数,则中值定义为第N/2个最小元;若N是奇数,则中值定义为第(N+1)/2个最小元。

输入格式:

输入第一行给出正整数N(<= 105)。随后N行,每行给出一个操作指令,为下列3种指令之一:

Push key

Pop

PeekMedian

其中Push表示入栈,key是不超过105的正整数;Pop表示出栈;PeekMedian表示查中值。

输出格式:

对每个入栈指令,将key入栈,并不输出任何信息。对每个出栈或查中值的指令,在一行中打印相应的返回结果。若指令非法,就打印“Invalid”。

题解:建立2个set,一个存小于中位数的部分,一个存大于中位数的部分,可以用S.erase(S.find(x))删除某个特定元素,记得每次操作后平衡2个set的size

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<‘ ‘; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<‘ ‘;                        cout<<a[i][m]<<endl;                         }
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch==‘-‘) f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-‘0‘; ch=getchar();}
    return x*f;
}
#define MAXN (100000+10)
int st[MAXN],sz=0;
multiset<int> S1,S2;
multiset<int>::iterator it;
int sz1=0,sz2=0;
int mid=0;
int find_s1_max(){
    if (S1.empty()) return 0;
    it=S1.end(); it--;
    return *it;
}
int find_s2_min(){
    if (S2.empty()) return  INF;
    it=S2.begin();
    return *it;
}

void balance() {
    while (sz1<sz2-1) {
        int t=find_s2_min();
        S2.erase(S2.find(t));--sz2;
        S1.insert(t);++sz1;
    }
    while (sz1>sz2) {
        int t=find_s1_max();
        S1.erase(S1.find(t));--sz1;
        S2.insert(t);++sz2;
    }
    if (sz1==sz2-1) mid=find_s2_min();
    else mid=find_s1_max();
}
void pri(set<int> &S) {
    cout<<"s:";
    for(it=S.begin();it!=S.end();it++)
    {
        cout<<*it<<‘ ‘;
    }
    cout<<endl;
}
char s[100];
int main()
{
    freopen("L302.in","r",stdin);
//  freopen(".out","w",stdout);

    int n=read();
    while(n--) {
        scanf("%s",s);
        if (s[1]==‘o‘) {
            if (!sz) {
                puts("Invalid");
                continue;
            }
//          pri(S1);pri(S2);
            if (S1.find(st[sz])!=S1.end()) S1.erase(S1.find(st[sz])),--sz1;
            else S2.erase(S2.find(st[sz])),--sz2;
            printf("%d\n",st[sz--]); 

        } else if (s[1]==‘u‘) {
            st[++sz]=read();
            if (st[sz]<mid) S1.insert(st[sz]),++sz1;
            else S2.insert(st[sz]),++sz2;
        } else {
            if (!sz) {
                puts("Invalid");
                continue;
            }
            printf("%d\n",mid);
        }
        balance();
    } 

    return 0;
}

L3-006. 迎风一刀斩

刘汝佳

迎着一面矩形的大旗一刀斩下,如果你的刀够快的话,这笔直一刀可以切出两块多边形的残片。反过来说,如果有人拿着两块残片来吹牛,说这是自己迎风一刀斩落的,你能检查一下这是不是真的吗?

注意摆在你面前的两个多边形可不一定是端端正正摆好的,它们可能被平移、被旋转(逆时针90度、180度、或270度),或者被(镜像)翻面。

这里假设原始大旗的四边都与坐标轴是平行的。

输入格式:

输入第一行给出一个正整数N(<=20),随后给出N对多边形。每个多边形按下列格式给出:

k x1 y1 … xk yk

其中k(2 < k <= 10)是多边形顶点个数;(xi, yi)(0 <= xi, yi <= 108)是顶点坐标,按照顺时针或逆时针的顺序给出。

注意:题目保证没有多余顶点。即每个多边形的顶点都是不重复的,任意3个相邻顶点不共线。

输出格式:

对每一对多边形,输出”YES”或者”NO”。

分情况讨论

首先枚举旋转,枚举镜像操作,枚举起点,枚举顺/逆时针

在分为4种情况考虑:

2个全等三角形

直角梯形+三角形

2个直角梯形

五边形+三角形

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<‘ ‘; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<‘ ‘;                        cout<<a[i][m]<<endl;                         }
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch==‘-‘) f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-‘0‘; ch=getchar();}
    return x*f;
}
int n;

ll sqr(ll a){return a*a;}
ld sqr(ld a){return a*a;}
double sqr(double a){return a*a;}

ld PI = 3.141592653589793238462643383;
class P{
public:
    double x,y;
    P(double x=0,double y=0):x(x),y(y){}
    friend long double dis2(P A,P B){return sqr(A.x-B.x)+sqr(A.y-B.y);  }
    friend long double Dot(P A,P B) {return A.x*B.x+A.y*B.y; }
    friend long double Length(P A) {return sqrt(Dot(A,A)); }
    friend long double Angle(P A,P B) {return acos(Dot(A,B) / Length(A) / Length(B) ); }

    friend P operator- (P A,P B) { return P(A.x-B.x,A.y-B.y); }
    friend P operator+ (P A,P B) { return P(A.x+B.x,A.y+B.y); }
    friend P operator* (P A,double p) { return P(A.x*p,A.y*p); }
    friend P operator/ (P A,double p) { return P(A.x/p,A.y/p); }
    friend bool operator< (const P& a,const P& b) {return a.x<b.x||(a.x==b.x&& a.y<b.y);}

};
const double eps=1e-2;
int dcmp(double x) {
    if (fabs(x)<eps) return 0; else return x<0 ? -1 : 1;
}
bool operator==(const P& a,const P& b) {
    return dcmp(a.x-b.x)==0 && dcmp(a.y-b.y) == 0;
} 

bool operator!=(const P& a,const P& b) {
    return !(a==b);
}
typedef P V;

V Rotate(V A,double rad) {
    return V(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
}
// A 不是 0向量 

P read_point() {
    P a;
    scanf("%lf%lf",&a.x,&a.y);
    return a;
}
int k1,k2;
P A[30],B[30];
bool check1(vector<P> &poly1,vector<P> &poly2) {
    cout<<setiosflags(ios::fixed)<<setprecision(0);
    V v1=poly1[0],v2=poly2[0];
    Rep(i,3) poly1[i]=poly1[i]-v1,poly2[i]=poly2[i]-v2;
    if (poly1[1]!=poly2[1]) return 0;
    Rep(i,3) if (poly1[i]!=poly2[i]) return 0;
    if (dcmp(poly1[1].x) != 0 || dcmp(poly1[2].y) != 0) return 0;
    return 1;
}
bool check2(vector<P> &poly1,vector<P> &poly2) {
    V v1=poly1[0],v2=poly2[0];
    Rep(i,4) poly1[i]=poly1[i]-v1;
    Rep(i,3) poly2[i]=poly2[i]-v2;
    if (poly1[1]!=poly2[1]) return 0;
    if (dcmp(poly1[3].y) != 0 || dcmp(poly1[2].y-poly1[1].y) != 0 ) return 0;
    if (dcmp(poly2[1].x) != 0 || dcmp(poly2[2].y) != 0) return 0;
    if (dcmp(poly1[2].x-poly1[3].x-poly2[2].x ) != 0 ) return 0;
    return 1;
}
bool check3(vector<P> &poly1,vector<P> &poly2) {
    V v1=poly1[0],v2=poly2[0];
    Rep(i,4) poly1[i]=poly1[i]-v1;
    Rep(i,4) poly2[i]=poly2[i]-v2;
    if (poly1[1]!=poly2[1]) return 0;
    if (dcmp(poly1[3].y) != 0 || dcmp(poly1[2].y-poly1[1].y) != 0 ) return 0;
    if (dcmp(poly2[3].y) != 0 || dcmp(poly2[2].y-poly2[1].y) != 0 ) return 0;
    if (dcmp(poly1[1].x) != 0 ) return 0;
    if (dcmp(poly1[2].x-poly1[3].x-poly2[2].x +poly2[3].x ) != 0 ) return 0;
    return 1;
}
bool check4(vector<P> &poly1,vector<P> &poly2) {
    V v1=poly1[0],v2=poly2[0];
    Rep(i,5) poly1[i]=poly1[i]-v1;
    Rep(i,3) poly2[i]=poly2[i]-v2;
    if (dcmp(poly1[4].y) != 0 || dcmp(poly1[2].y-poly1[1].y) != 0 ) return 0;
    if (dcmp(poly1[1].x) != 0 || dcmp(poly1[4].x-poly1[3].x) != 0 ) return 0;
    if (dcmp(poly1[2].x-poly1[3].x)>=0 || dcmp(poly1[2].y -poly1[3].y) <=0  ) return 0;
    if (dcmp(poly2[1].x) != 0 || dcmp(poly2[2].y) != 0) return 0;
    if (dcmp(poly1[2].x-poly1[3].x+poly2[2].x) !=0 || dcmp(poly1[2].y -poly1[3].y - poly2[1].y) !=0 ) return 0;
    return 1;
}

bool checkT() {
    for(int b1=-1;b1<=1;b1+=2)
        for(int b2=-1;b2<=1;b2+=2)
            Rep(i,k1)
                Rep(j,k2) {
                    vector<P> poly1,poly2;
                    Rep(k,k1)
                        poly1.pb(A[(i+b1*k+k1)%k1]);
                    Rep(l,k2)
                        poly2.pb(B[(j+b2*l+k2)%k2]);
                    if (k1==3&&k2==3) if (check1(poly1,poly2)) return 1;
                    if (k1==4&&k2==3) if (check2(poly1,poly2)) return 1;
                    if (k1==4&&k2==4) if (check3(poly1,poly2)) return 1;
                    if (k1==5&&k2==3) if (check4(poly1,poly2)) return 1;

                }
    return 0;
}
bool check() {
    Rep(k,4) {
        Rep(i,k1) A[i]=Rotate(A[i],PI/2);
        Rep(l,4) {
            Rep(i,k2) B[i]=Rotate(B[i],PI/2);
            if (checkT()) return 1;
        }
    }
    Rep(i,k1) A[i].x*=-1;
    Rep(k,4) {
        Rep(i,k1) A[i]=Rotate(A[i],PI/2);
        Rep(l,4) {
            Rep(i,k2) B[i]=Rotate(B[i],PI/2);
            if (checkT()) return 1;
        }
    }
    Rep(i,k1) A[i].x*=-1;
    Rep(i,k2) B[i].x*=-1;
    Rep(k,4) {
        Rep(i,k1) A[i]=Rotate(A[i],PI/2);
        Rep(l,4) {
            Rep(i,k2) B[i]=Rotate(B[i],PI/2);
            if (checkT()) return 1;
        }
    }
    Rep(i,k1) A[i].x*=-1;
    Rep(k,4) {
        Rep(i,k1) A[i]=Rotate(A[i],PI/2);
        Rep(l,4) {
            Rep(i,k2) B[i]=Rotate(B[i],PI/2);
            if (checkT()) return 1;
        }
    }
    return 0;
}

int main()
{
//  freopen("L306.in","r",stdin);
//  freopen("l306.out","w",stdout);
    cin>>n;
    while(n--) {
        cin>>k1;
        Rep(i,k1) A[i]=read_point();
        cin>>k2;
        Rep(i,k2) B[i]=read_point();
        if (k1<k2) {
            Rep(i,k2) swap(A[i],B[i]);
            swap(k1,k2);
        }
        if(check()) puts("YES"); else puts("NO");
    }

    return 0;
}
时间: 2024-10-13 22:58:54

PAT 团体程序设计天梯赛 部分题目题解的相关文章

PTA|团体程序设计天梯赛-练习题目题解锦集(C/C++)(持续更新中……)

PTA|团体程序设计天梯赛-练习题目题解锦集(持续更新中) 实现语言:C/C++:      欢迎各位看官交流讨论.指导题解错误:或者分享更快的方法!! 题目链接:https://pintia.cn/problem-sets/994805046380707840/problems 目录 (点击对应题目即可进入相应题解--小声BB--) L1-001 Hello World (5 分) L1-002 打印沙漏 (20 分) L1-003 个位数统计 (15 分) L1-004 计算摄氏温度 (5

PAT 团体程序设计天梯赛-练习集 题解(凑零钱,堆栈,社交集群)

开始准备cccc(cry)天梯赛了,第一周训练题,把官网挂出的训练题刷完了,对pat有了一点点的熟悉感. L1-1  就不说了... L1-2 打印沙漏 一个变量保存空格数,一个变量保存沙漏符号数,打印就行了,但这题话说wrong好几次啊,坑点是沙漏符号后面不打印空格,orz... <span style="font-size:14px;">#include<iostream> #include<stdio.h> #include<math.h

PAT 团体程序设计天梯赛-练习集L1-011. A-B

本题要求你计算A-B.不过麻烦的是,A和B都是字符串 —— 即从字符串A中把字符串B所包含的字符全删掉,剩下的字符组成的就是字符串A-B. 输入格式: 输入在2行中先后给出字符串A和B.两字符串的长度都不超过104,并且保证每个字符串都是由可见的ASCII码和空白字符组成,最后以换行符结束. 输出格式: 在一行中打印出A-B的结果字符串. 输入样例: I love GPLT! It's a fun game! aeiou 输出样例: I lv GPLT! It's fn gm! 1 #inclu

PAT 团体程序设计天梯赛-练习集 L1-015. 跟奥巴马一起画方块

美国总统奥巴马不仅呼吁所有人都学习编程,甚至以身作则编写代码,成为美国历史上首位编写计算机代码的总统.2014年底,为庆祝“计算机科学教育周”正式启动,奥巴马编写了很简单的计算机代码:在屏幕上画一个正方形.现在你也跟他一起画吧! 输入格式: 输入在一行中给出正方形边长N(3<=N<=21)和组成正方形边的某种字符C,间隔一个空格. 输出格式: 输出由给定字符C画出的正方形.但是注意到行间距比列间距大,所以为了让结果看上去更像正方形,我们输出的行数实际上是列数的50%(四舍五入取整). 输入样例

PAT 团体程序设计天梯赛-练习集 L1-007. 念数字

输入一个整数,输出每个数字对应的拼音.当整数为负数时,先输出“fu”字.十个数字对应的拼音如下: 0: ling 1: yi 2: er 3: san 4: si 5: wu 6: liu 7: qi 8: ba 9: jiu 输入格式: 输入在一行中给出一个整数,如: 1234 . 提示:整数包括负数.零和正数. 输出格式: 在一行中输出这个整数对应的拼音,每个数字的拼音之间用空格分开,行末没有最后的空格.如 yi er san si. 输入样例: -600 输出样例: fu liu ling

PAT 团体程序设计天梯赛-练习集 L1-005. 考试座位号

每个PAT考生在参加考试时都会被分配两个座位号,一个是试机座位,一个是考试座位.正常情况下,考生在入场时先得到试机座位号码,入座进入试机状态后,系统会显示该考生的考试座位号码,考试时考生需要换到考试座位就座.但有些考生迟到了,试机已经结束,他们只能拿着领到的试机座位号码求助于你,从后台查出他们的考试座位号码. 输入格式: 输入第一行给出一个正整数N(<=1000),随后N行,每行给出一个考生的信息:“准考证号 试机座位号 考试座位号”.其中准考证号由14位数字组成,座位从1到N编号.输入保证每个

PAT 团体程序设计天梯赛-练习集 L1-016. 查验身份证

一个合法的身份证号码由17位地区.日期编号和顺序编号加1位校验码组成.校验码的计算规则如下: 首先对前17位数字加权求和,权重分配为:{7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2}:然后将计算的和对11取模得到值Z:最后按照以下关系对应Z值与校验码M的值: Z:0 1 2 3 4 5 6 7 8 9 10M:1 0 X 9 8 7 6 5 4 3 2 现在给定一些身份证号码,请你验证校验码的有效性,并输出有问题的号码. 输入格式: 输入第一行给出正整数N(<= 100

PAT 团体程序设计天梯赛-练习集 L1-017. 到底有多二

一个整数“犯二的程度”定义为该数字中包含2的个数与其位数的比值.如果这个数是负数,则程度增加0.5倍:如果还是个偶数,则再增加1倍.例如数字“-13142223336”是个11位数,其中有3个2,并且是负数,也是偶数,则它的犯二程度计算为:3/11*1.5*2*100%,约为81.82%.本题就请你计算一个给定整数到底有多二. 输入格式: 输入第一行给出一个不超过50位的整数N. 输出格式: 在一行中输出N犯二的程度,保留小数点后两位. 输入样例: -13142223336 输出样例: 81.8

【题解】PAT团体程序设计天梯赛 - 模拟赛

由于本人愚笨,最后一题实在无力AC,于是只有前14题的题解Orz 总的来说,这次模拟赛的题目不算难,前14题基本上一眼就有思路,但是某些题写起来确实不太容易,编码复杂度有点高~ L1-1 N个数求和 设计一个分数类,重载加法运算符,注意要约分,用欧几里得算法求个最大公约数即可. 1 #include <cstdio> 2 3 long long abs(long long x) 4 { 5 return x < 0 ? -x : x; 6 } 7 8 long long gcd(long