1 条题解
-
0
自动搬运
来自洛谷,原作者为

canwen
你已经初三了初三了初三了 || 2025CSP RP++ || 争取今年不退役/ll搬运于
2025-08-24 22:58:28,当前版本为作者最后更新于2024-07-20 13:11:47,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题意
简化题意:输入每张表格,并用语句查询表格内容。
张表格,每个表格 行 列,第一行为表头。
次 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];以上分别记录每个表格名字,每个表格的表头,每张表格除第一行(也就是除去表头)的内容,每张表格的长度 和宽度 。
这样一来,输入的问题就解决了。
如何查询呢?我们可以编写函数分别查找一个表格名字是第几个,一个表头在每张表格里的第几列。
输入字符串,截取每个字符串的有用部分。
可以用 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
- 上传者