Coderforces 730H 730G

题目链接点击打开链接


题意:有n个字符串,要删除指定的m个, 若可以可以删除,输出Yes,找出其通用模式(?可匹配单个任何字母) ,否则输出No

思路: 直接模拟 , 先找出通用模式,若可以找出,则判断该模式会不会删除不该删除的字符串,否则输出No

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
const int maxn = 105 ;
char word[maxn][maxn] , result[maxn] ;
bool delet[maxn] ;

bool to_delet(char A[] , char B[]) // is to delete
{
    int len1 = strlen(A ) , len2 = strlen(B) ;
    if(len1!= len2) return false ;
    for(int i = 0 ; i < len1 ; i ++)
    {
        if(A[i] == '?') continue ;
        if(A[i] != B[i]) return false ;
    }
    return true ;
}

int main()
{
    //freopen("a.txt" , "r" , stdin) ;
    int n , m , a , length;
    bool judge ;
    while(scanf("%d%d\n"  , &n , &m)  != EOF)
    {
        memset(delet , 0 , sizeof(delet)) ; //初始化
        judge = true ;
        for(int i = 1 ; i <= n ; i ++)
            scanf("%s" , word[i]) ;
        scanf("%d" , &a) ;
        delet[a] = true ;
        length = strlen(word[a]) ; //记录第一个要被删除的单词的长度
        for(int i = 0 ; i < length ; i ++)
            result[i] = word[a][i] ;   //把第一个要被删除的单词的结果记录为result
        for(int i = 2 ; i <= m ; i ++)
        {
            scanf("%d" , &a) ;
            delet[a] = true ;
            if(length != strlen(word[a])) judge = false ; //如果后需要被删除的但此时的长度和第一个不同,则标记为假
        }
        if(! judge )
        {
            printf("No\n") ;
            continue ;
        }

        for(int j = 0 ; j < length ; j ++)   //提取公共模式
        {
            for(int i = 1 ; i <= n ; i ++)
            {
                if(delet[i])
                {
                    if(word[i][j] != result[j])    //字符不同的话,记为?
                    { result[j] = '?' ; break; }
                }
            }
        }

        for(int i = 1 ; i <= n ; i ++)   
        {
            if(delet[i] == false)     //判断公共模式会不会删除不该删除的
            {
                if(to_delet(result , word[i]))
                {
                    judge = false ; break ;
                }
            }
        }

        if(!judge)
        {
            printf("No\n") ; continue ;
        }
        else
        {
            printf("Yes\n") ;
            for(int j = 0 ; j < length ; j ++)
                printf("%c" , result[j]) ;
            printf("\n") ;
        }
    }
    return 0;
}

题目链接: 点击打开链接

题意:某修车厂依次接到了n份修理请求,s表示期望修理日期,d表示需要的修理时间。 若在整个修理期间,修车厂空闲,则满足客户要求,从第s天开始修理车。否则找出一个空闲的最早时间段(大于等于d),在该时间段修理汽车。 输出每辆汽车被修理的起始和终止时间。

思路:记录停车场的每个空闲时间段的起始终止时间,和时间段长度。 依次对每个请求检查请求时间段是否为空闲时间段,若是则输出,否则从第一个空闲时间段开始查找一个时间段满足(length >= d),并输出;

#include<stdio.h>
#include<string.h>
#include <iostream>
const int maxn = 300 ;
using namespace std ;
struct Node
{
    int x , y;
    int length ;
}T[maxn];

void Init()
{
    for(int i = 1 ; i < maxn ; i ++)
    {
        T[i].x = 1 ; T[i].length = 1e9 + 1e8 + 2 ;
        T[i].y = T[i].x +T[i].length -1 ;
    }
}

void out(int num)
{
    for(int i = 1 ; i <= num ; i ++)
    printf("x=%d y=%d len=%d\n" , T[i].x , T[i].y , T[i].length) ;
}

int main()
{
	//freopen("a.txt" , "r" , stdin) ;
    int n , a , b , number ,  IsInput;
	while(scanf("%d" , &n) != EOF)
    {
        Init() ;
        number = 1  ;
        for(int i = 1 ; i <= n ; i ++)
        {
            scanf("%d%d" , &a , &b) ;
           // printf("a=%d b=%d\n" , a , b) ;
            IsInput = 0 ;
            for(int i = number ; i >= 1 ; i --)
            {
                if(T[i].x <= a && T[i].y >= a+b-1 )
                {
                    IsInput = 1 ;
                    printf("%d %d\n", a , a+b-1) ;
                    if(T[i].x== a && T[i].y == a+b-1)
                    {
                        for(int j = i + 1 ; j <= number ; j ++)
                        {
                            T[j-1].x = T[j].x ;
                            T[j-1].y = T[j].y ;
                            T[j-1].length = T[j].length ;
                        }
                        number -- ;
                    }
                    else if(T[i].x == a)
                    {
                        T[i].x = a+b ;
                        T[i].length = T[i].y - T[i].x + 1 ;
                    }
                    else if(T[i].y == a+b-1)
                    {
                        T[i].y = a - 1 ;
                        T[i].length = T[i].y - T[i].x + 1 ;
                    }
                    else
                    {
                        number ++ ;
                        int temp = T[i].y ;
                        T[i].y = a - 1 ;
                        T[i].length = T[i].y - T[i].x + 1 ;
                        for(int j = number - 1 ; j > i ; j --)
                        {
                            T[j+1].x = T[j].x ;
                            T[j+1].y = T[j].y ;
                            T[j+1].length = T[j+1].y - T[j+1].x + 1 ;
                        }
                        T[i+1].x = a+b ;
                        T[i+1].y = temp ;
                        T[i+1].length = T[i+1].y - T[i+1].x + 1 ;
                    }
                }
                else if(T[i].y < a ) break ;
            }
           // out(number) ;
            int Infront ;
            //cout << "flag="<<flag<<endl ;
            if(!IsInput)
            {
                 Infront = 0 ;
                for(int i = 1 ; i <= number ; i ++)
                {
                    if(T[i].length >= b)
                    {
                       // printf("i=%d len=%d a=%d b=%d\n" , i ,T[i].length , a , b) ;
                        Infront = 1 ;
                       printf("%d %d\n" , T[i].x , T[i].x + b -1) ;
                        if(T[i].length == b)
                        {
                            for(int j = i + 1 ; j <= number ; j ++)
                            {
                                T[j-1].x = T[j].x ;
                                T[j-1].y = T[j].y ;
                                T[j-1].length = T[j].length ;
                            }
                            number -- ;
                        }
                        else {
                            T[i].x = T[i].x + b ;
                            T[i].length = T[i].y - T[i].x + 1 ;
                        }
                        break ;
                    }
                }
            }
          // cout<< Infront<<endl ;

        }
    }
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值