1 条题解

  • 0
    @ 2025-8-24 22:58:28

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar canwen
    你已经初三了初三了初三了 || 2025CSP RP++ || 争取今年不退役/ll

    搬运于2025-08-24 22:58:28,当前版本为作者最后更新于2024-07-20 13:11:47,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    题意

    简化题意:输入每张表格,并用语句查询表格内容。

    nn 张表格,每个表格 xxyy 列,第一行为表头。

    mm 次 sql 语句查询,格式是 select [columns] from [table_name] where [header]=x,输出在 table_name 这张表格里,header 这一表头的这一列中值为 x 的那一行的 columns 列的值,且 columns 里可能有多个要输出的表头名。

    分析

    数据范围很小,主要思路是模拟

    我们可以定义如下数组。

    string name[11],title[11][11],excel[11][101][11];
    int xx[11],yy[11];
    

    以上分别记录每个表格名字,每个表格的表头,每张表格除第一行(也就是除去表头)的内容,每张表格的长度 xx 和宽度 yy

    这样一来,输入的问题就解决了。

    如何查询呢?我们可以编写函数分别查找一个表格名字是第几个,一个表头在每张表格里的第几列。

    输入字符串,截取每个字符串的有用部分。

    可以用 cstring 库中带有的 substr() 函数来进行截取,比较方便。

    对于可以输入多个表头名的 columns,我们可以记录一下其中逗号出现的位置,这样模拟会比较方便。特殊的,要判断一下没有逗号出现的情况。

    完成上述预备环节之后,就可以愉快地枚举了。

    可以参考下面的代码。

    Code

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    
    string name[11],title[11][11],excel[11][101][11];//表格名字,每张表的表头,表格整体内容 
    int xx[11],yy[11],d[150];//每张表的x,y长度 & 逗号出现的位置 
    
    int n;//n张表 
    
    int f1(string a){
    	//返回是第几个表格的名字
    	for(int i=1;i<=n;i++){
    		if(name[i]==a) return i;
    	} 
    }
    
    int f2(int a,string b){
    	//第a个表中的 b表头的纵坐标
    	for(int i=1;i<=yy[a];i++){
    		if(title[a][i]==b) return i;
    	}
    } 
    
    void put(int a,int b,int c){
    	//输出内容 
    	cout<<excel[a][b][c]<<" ";
    	return;
    }
    
    signed main(){
    	cin>>n;
    	
    	for(int i=1;i<=n;i++){
    		cin>>name[i];//输入表格名字 
    		int x,y;cin>>x>>y;
    		for(int j=1;j<=y;j++) cin>>title[i][j];//先单独输入表头在title数组,方便判断 
    		x--,xx[i]=x,yy[i]=y; //除去表头这一行,剩下 x-1 行 
    		for(int j=1;j<=x;j++){
    			for(int k=1;k<=y;k++){
    				cin>>excel[i][j][k];
    			}
    		}
    	}
    	 
    	int m;cin>>m;
    	for(int i=1;i<=m;i++){
    		//select [columns] from [table_name] where [header]=x 
    		string out;cin>>out>>out;//记录 `columns`
    		int len=0;//记录多少个逗号
    		memset(d,0,sizeof(d));//初始化 
    		for(int j=0;j<out.size();j++) 
    			if(out[j]==',') d[++len]=j;
    		
    		string which;cin>>which>>which;//记录 `table_name`
    		int num=f1(which);//调用函数查询是第几个表格的名字 
    		
    		string tmp;cin>>tmp>>tmp;
    		int tmp1=tmp.find('=');/*查找等号出现的位置*/
    		string pd1=tmp.substr(0,tmp1),pd2=tmp.substr(tmp1+1);//截取
    		
    		
    		int num2=f2(num,pd1);//查询表头是第几列,方便枚举 
    		
    		for(int j=1;j<=xx[num];j++){
    			if(excel[num][j][num2]==pd2){//找到了符合条件的 
    				
    				if(len==0){
    					//特判单个表头名的 
    					put(num,j,f2(num,out));
    				}else{
    					for(int k=1;k<=len+1;k++){
    						string awa;
    						if(k==1) awa=out.substr(0,d[k]);
    						else if(k==len+1) awa=out.substr(d[k-1]+1);
    						else awa=out.substr(d[k-1]+1,d[k]-d[k-1]-1);
    						put(num,j,f2(num,awa));
    						//上述是推出来的截取计算式 
    						//k==1 0,d[k]
    						//k==2 d[k-1]+1,d[k]-d[k-1]-1
    						//k==len+1 d[k-1]+1
    					}
    				}
    				printf("\n");
    			}
    		}
    	}
    	
    	return 0;//good habit~
    }
    

    下面补充一下上面的代码中出现的在 cstring 库中的函数的使用方法。

    #include<cstring>
    #include<iostream>
    using namespace std;
    
    int main(){
    	string a="abcd";
    	//a.substr(x,y) 截取字符串 a 从下标 x 位置开始,连续的 y 个字符 
    	cout<<a.substr(0,2)<<endl;//输出 `ab`
    	cout<<a.substr(1)<<endl;//若没有传进 y,默认从下标 x 位置开始截取到末尾,输出 `bcd` 
        //a.find(x) 返回 x 在 a 中的位置(下标从0开始)
        cout<<a.find('d')<<endl;//输出3
    	return 0;
    }
    
    • 1

    信息

    ID
    10556
    时间
    3000ms
    内存
    512MiB
    难度
    3
    标签
    递交数
    0
    已通过
    0
    上传者