1 条题解

  • 0
    @ 2025-5-4 16:10:50

    分析:

    该代码主要运用了贪心算法和模拟算法。贪心算法用于对规则按照开始时间和结束时间进行排序,以便后续高效处理;模拟算法用于根据输入的呼叫时间和规则,模拟电话呼叫的转发过程,确定每个呼叫最终的目标号码。

    解题思路

    本题的目标是根据一系列电话呼叫转发规则,模拟电话呼叫的转发过程,确定每个呼叫最终的目标号码。解题的核心思路是先对规则进行排序,然后按照时间顺序模拟呼叫,根据规则的开始和结束时间更新目标号码,最后确定每个呼叫的最终目标号码并输出。

    解题原理

    1.规则排序:使用 sort 函数对规则数组 byBeg 和 byEnd 分别按照开始时间 beg 和结束时间 end 进行排序。这样可以方便地在后续模拟过程中按照时间顺序处理规则的生效和失效。

    2.时间推进与规则处理:通过一个循环不断推进时间,在每个时间点检查是否有新规则生效(开始时间等于当前时间)或旧规则失效(结束时间等于当前时间)。如果有新规则生效,将对应的源号码的目标号码更新为规则中的目标号码;如果有旧规则失效,将对应的源号码的目标号码重置为 0。

    3.呼叫转发模拟:对于每个输入的呼叫,根据当前时间找到最新的规则状态,确定呼叫的目标号码。如果目标号码在转发过程中出现循环(即最终目标号码又回到了原始呼叫号码),则将目标号码设置为 9999。

    实现步骤

    1.输入处理:读取系统数量 n,对于每个系统,读取一系列电话呼叫转发规则,每条规则包含源号码 src、开始时间 beg、持续时间 end 和目标号码 dest。同时读取一系列呼叫记录,每条记录包含呼叫时间 sj 和呼叫号码 call。

    2.规则排序:对规则数组 byBeg 和 byEnd 分别按照开始时间 beg 和结束时间 end 进行排序。

    3.时间推进与规则处理:初始化时间 jd 和规则处理位置 begPos、endPos。通过一个循环不断推进时间,在每个时间点检查是否有新规则生效或旧规则失效,根据情况更新目标号码数组 target。

    4.呼叫转发模拟:对于每个呼叫记录,根据当前时间找到最新的规则状态,确定呼叫的目标号码。如果目标号码在转发过程中出现循环,则将目标号码设置为 9999。

    5.输出结果:按照指定格式输出每个呼叫的呼叫时间、呼叫号码和最终目标号码。

    c++代码:

    #include <stdio.h>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    
    struct rule{
    	int src;
    	int dest;
    	int beg;
    	int end;
    }byBeg[110], byEnd[110];
    
    void print(int n){
    	if(n<10) printf("000");
    	else if(n<100) printf("00");
    	else if(n<1000) printf("0");
    	printf("%d",n);
    }
    
    bool cmpBeg(const rule& r1, const rule& r2){
    	return r1.beg < r2.beg;
    }
    
    bool cmpEnd(const rule& r1, const rule& r2){
    	return r1.end < r2.end;
    }
    
    int target[10000];
    int rNum;
    
    void init(){
    	for(int i = 0; i < 10000; i++){
    		target[i] = 0;
    	}
    	rNum = 0;
    }
    
    int mn(int x, int y){return (x<y)? x: y;}
    
    int main(){
    	printf("CALL FORWARDING OUTPUT\n");
    	int n;
    	scanf("%d",&n);
    	for(int ii = 1; ii <= n; ii++){
    		printf("SYSTEM %d\n",ii);
    		init();
    		int src, beg, end, dest;
    		while(1){
    			//cout << "hehe" << endl;
    			scanf("%d",&src);
    			//cout << src << endl;
    			if(!src) { break;}
    			scanf("%d%d%d",&beg, &end, &dest);
    			byBeg[rNum].src = src, byBeg[rNum].beg = beg, byBeg[rNum].end = beg+end+1, byBeg[rNum].dest = dest;
    			byEnd[rNum] = byBeg[rNum];
    			rNum++;
    		}
    		//cout << "hehe" << endl;
    		sort(byBeg, byBeg+rNum, cmpBeg);
    		sort(byEnd, byEnd+rNum, cmpEnd);
    		int begPos = 0, endPos = 0;
    		int jd = -1;
    		while(1){
    			int sj, call;
    			scanf("%d",&sj);
    			if(sj==9000) break;
    			scanf("%d",&call);
    			jd++;
    			while(jd <= sj){
    				int nextJd = sj+1;
    				if(begPos < rNum) nextJd = mn(nextJd, byBeg[begPos].beg);
    				if(endPos < rNum) nextJd = mn(nextJd, byEnd[endPos].end);
    				if(nextJd == sj+1) break;
    				jd = nextJd;
    				while(endPos < rNum && byEnd[endPos].end == jd){
    					target[byEnd[endPos].src] = 0;
    					endPos++;
    				}
    				while(begPos < rNum && byBeg[begPos].beg == jd){
    					target[byBeg[begPos].src] = byBeg[begPos].dest;
    					begPos++;
    				}
    			}
    			jd = sj;
    			int dest = target[call];
    			if(dest == 0) dest = call;
    			else{
    				bool cycle = 0;
    				while(target[dest] != 0){
    					dest = target[dest];
    					if(dest == call){
    						cycle = 1;
    						break;
    					}
    				}
    				if(cycle) dest = 9999;
    			}
    			printf("AT ");
    			print(sj);
    			printf(" CALL TO ");
    			print(call);
    			printf(" RINGS ");
    			print(dest);
    			printf("\n");
    		}
    	}
    	printf("END OF OUTPUT\n");
    	return 0;
    }
    • 1

    信息

    ID
    527
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    3
    已通过
    1
    上传者