ACM 实验室2020.10.03天梯赛练习*1

7-6 情人节 (15分)

这个题错在定义循环数t不是从0开始而是从1开始的,然后就wa了

#include<bits/stdc++.h>
#define ll long long
#define speed_up ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
int main()
{
    speed_up;
    string s,s1,s2,s3;
    int t=0;
    while(cin>>s)
    {
        if(s[0]=='.')break;
        if(t==1)s1=s;
        if(t==13)s2=s;
        t++;
    }
    if(t>=14)
    {
        cout<<s1<<" and "<<s2<<" are inviting you to dinner..."<<endl;
    }
    else if(t<14&&t>=2)
    {
        cout<<s1<<" is the only one for you..."<<endl;
    }
    else if(t<2)
    {
        cout<<"Momo... No one is for you ..."<<endl;
    }
}

7-9 排座位 (25分)

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

输入第一行给出3个正整数:N≤100),即前来参宴的宾客总人数,则这些人从1到N编号;M为已知两两宾客之间的关系数;K为查询的条数。随后M行,每行给出一对宾客之间的关系,格式为:宾客1 宾客2 关系,其中关系为1表示是朋友,-1表示是死对头。注意两个人不可能既是朋友又是敌人。最后K行,每行给出一对需要查询的宾客编号。

这里假设朋友的朋友也是朋友。但敌人的敌人并不一定就是朋友,朋友的敌人也不一定是敌人。只有单纯直接的敌对关系才是绝对不能同席的。

对每个查询输出一行结果:如果两位宾客之间是朋友,且没有敌对关系,则输出No problem;如果他们之间并不是朋友,但也不敌对,则输出OK;如果他们之间有敌对,然而也有共同的朋友,则输出OK but...;如果他们之间只有敌对关系,则输出No way

建立二维数组存图,存入每个人之间的关系,查询时当两个人是敌对关系,要从二维数组中遍历找他们是否有共同的朋友或敌对,然后输出就行了。

#include<bits/stdc++.h>
#define ll long long
#define speed_up ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
int main()
{
    speed_up;
    int n,m,k;
    cin>>n>>m>>k;
    int l[101][101]={0};
    for(int i=0;i<m;i++)
    {
        int a,b,c;
        cin>>a>>b>>c;
        l[a][b]=c;
        l[b][a]=c;
    }
    for(int i=0;i<k;i++)
    {
        int x,y,f=0;
        cin>>x>>y;
        if(l[x][y]==-1)
        {
            for(int j=0;j<n;j++)
            {
                if(l[j][x]*l[j][y]==1)//两个人有共同的朋友或有共同的敌人
                {
                    f=1;
                    break;
                }
            }
            if(f==1)cout<<"OK but..."<<endl;
            else cout<<"No way"<<endl;
        }
        else if(l[x][y]==0)
        {
            cout<<"OK"<<endl;
        }
        else if(l[x][y]==1)
        {
            cout<<"No problem"<<endl;
        }
    }
}

7-10 最长对称子串 (25分)

输入一个带空格的字符串,求最长对称字串

比较两次,先从两头开始比较,找到一个两头字符相等的子串就用函数再比较该字串是否对称。刚开始写复杂了,写的分两种情况从一个数向两边比较,最大N全对称全不对称最短串的测试点都没过。

#include<bits/stdc++.h>
#include<algorithm>
#define ll long long
using namespace std;
#define speed_up ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
bool compare(string s)//判断子串是否对称
{
    for(int i=0;i<s.length();i++)
    {
        if(s[i]==s[s.length()-i-1])continue;//也是从两边向中间比较
        else return false;
    }
    return true;
}
int main()
{
    speed_up;
    string s,s1;
    int c=0,maxx=0;
    getline(cin,s);//注意输入可能包含空格
    for(int i=0;i<s.length();i++)
    {
        for(int j=s.length();j>=i;j--)//从后往前比较
        {
            if(s[i]==s[j])
            {
                s1=s.substr(i,j-i+1);//截取这段并比较它是不是对称的
                if(compare(s1))
                {
                    c=s1.length();
                    if(c>maxx)maxx=c;
                }
            }
        }
    }
    cout<<maxx<<endl;
}

类似的做法:

#include<bits/stdc++.h>
#define ll long long
#include<string>
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<cmath>
#include<string>
#include<map>
#include<sstream>
#include<cstring>
#include<vector>
#include<iomanip>
#include<queue>
#include<set>
#define speed_up ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;

int com(string s)
{
int m=0,f=0;
for(int i=0; i<s.size(); i++)
{
for(int j=s.size(); j>=i; j--)//注意这里的大于等于号,只写大于有一个测试点过不了(输入长度为1的字符串)
{
if(s[i]==s[j])
{
//cout<<s[i];
for(int ii=i,jj=j; ii<=jj; ii++,jj--)//没加等于号wa测试点4了
{
//cout<<s[ii];
if(s[ii]==s[jj])
f=0;
else
{
f=1;
break;
}
}
if(!f)
m=max(m,j-i+1);
}
//cout<<endl;
}
}
return m;
}
int main()
{
speed_up;
string s;
getline(cin,s);
cout<<com(s)<<endl;
}

 7-11 重排链表 (25分)

给定一个单链表 L1​​→L2​​→⋯→Ln1​​→Ln​​,请编写程序将链表重新排列为 Ln​​→L1​​→Ln1​​→L2​​→⋯。例如:给定L为1→2→3→4→5→6,则输出应该为6→1→5→2→4→3。

 

#include<bits/stdc++.h>
#define ll long long
#define speed_up ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
struct Node
{
    int add;
    int data;
    int next;
}link[100010];
int main()
{
    speed_up;
    vector<int>v;
    int ad1,n,ad;
    cin>>ad1>>n;
    for(int i=0;i<n;i++)
    {
        cin>>ad;
        cin>>link[ad].data;//将数据、下一节点地址、地址按存入结构体
        cin>>link[ad].next;
        link[ad].add=ad;
    }
    while(ad1!=-1)
    {
        v.push_back(ad1);//将地址存入数组
        ad1=link[ad1].next;
    }
    for(int i=0;i<v.size()/2;i++)
    {
        if(!i)printf("%05d %d ",v[n-i-1],link[v[n-i-1]].data);//倒序输出
        else printf("%05d\n%05d %d ",v[n-i-1],v[n-i-1],link[v[n-i-1]].data);
        printf("%05d\n%05d %d ",v[i],v[i],link[v[i]].data);//正序输出
    }
    if(n%2!=0)printf("%05d\n%05d %d ",v[n/2],v[n/2],link[v[n/2]].data);
    cout<<"-1";
    return 0;
}

7-12 分而治之 (25分)

输入在第一行给出两个正整数 N 和 M(均不超过10 000),分别为敌方城市个数(于是默认城市从 1 到 N 编号)和连接两城市的通路条数。随后 M 行,每行给出一条通路所连接的两个城市的编号,其间以一个空格分隔。在城市信息之后给出参谋部的系列方案,即一个正整数 K (≤ 100)和随后的 K 行方案,每行按以下格式给出:

Np v[1] v[2] ... v[Np]
 

其中 Np 是该方案中计划攻下的城市数量,后面的系列 v[i] 是计划攻下的城市编号。

输出格式:

对每一套方案,如果可行就输出YES,否则输出NO

 
定义一个set集合暂存要攻的城,如果能在set中只能找到联通桥一边的点,就不可行,反之如果能同时找到或同时找不到联通桥两边的点就可行。

#include<bits/stdc++.h>
#define ll long long
#define speed_up ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
int main()
{
    speed_up;
    int n,m;
    cin>>n>>m;
    int a[m][2];
    for(int i=0;i<m;i++)
    {
        cin>>a[i][0]>>a[i][1];
    }
    int t;
    cin>>t;
    while(t--)
    {
        int tt;
        cin>>tt;
        set<int>tmp;
        for(int i=1;i<=tt;i++)
        {
            int a;
            cin>>a;
            tmp.insert(a);
        }
        int f=0;
        for(int i=0;i<m;i++)
        {
            if(tmp.find(a[i][0])==tmp.end()&&tmp.find(a[i][1])==tmp.end())
            {
                f=1;
                break;
            }
        }
        if(f)cout<<"NO"<<endl;
        else cout<<"YES"<<endl;
    }
}

posted @ 2020-10-11 15:09  SyrupWRLD  阅读(149)  评论(0)    收藏  举报