求助,提交了 137 次了,都没有过.jpg
查看原帖
求助,提交了 137 次了,都没有过.jpg
60864
tiger2005楼主2021/7/16 19:47

后面会发出 AC 代码(肯定是别人的)。依赖于空行进行读入所以记得加上。

// Problem: UVA10757 Interpreting SQL
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/UVA10757
// Memory Limit: 0 MB
// Time Limit: 3000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cctype>
#include <string>
#include <queue>
#include <iostream>
#include <vector>
#include <map>
#include <set>

using namespace std;

struct Info{
	int typ;
	int typ_int;
	string typ_str;
	Info(int typ=0, int typ_int=0, string typ_str="")
		:typ(typ), typ_int(typ_int), typ_str(typ_str){}
	bool operator < (const Info& x)const{
		if(typ == 0)
			return typ_int < x.typ_int;
		return typ_str < x.typ_str;
	}
	bool operator > (const Info& x)const{
		return x < (*this);
	}
	bool operator <= (const Info& x)const{
		return !((*this) > x);
	}
	bool operator >= (const Info& x)const{
		return !((*this) < x);
	}
	bool operator == (const Info& x)const{
		if(typ != x.typ)	return false;
		return ((*this) >= x) && ((*this) <= x);
	}
	bool operator != (const Info& x)const{
		return !((*this) == x);
	}
	
};

inline string toU(string s){
	for(auto& x: s)
		if(x>='a' && x<='z')
			x = x-'a'+'A';
	return s;
}

inline bool chk(Info l, string cmp, Info r){
	if(cmp == "=")	return l == r;
	if(cmp == ">")	return l > r;
	if(cmp == "<")	return l < r;
	if(cmp == ">=")	return l >= r;
	if(cmp == "<=")	return l <= r;
	return l != r;
}

struct Table{
	vector<pair<string, char> > Col;
	map<string, int> Mp;
	vector<vector<Info> > In;
	string name;
	int Sr, Sc;
	Table(){
		Sr = Sc = 0;
		name = "";
		In.clear();
		Mp.clear();
		Col.clear();
	}
	void read(){
		cin >> name >> Sr >> Sc;
		string s; char ch;
		for(int i=0; i<Sr; i++){
			cin >> s >> ch;
			Col.emplace_back(s, ch);
			Mp[toU(s)] = i;
		}
		In.resize(Sc);
		for(auto& x: In)	x.resize(Sr);
		int tI = 0; string tR = "";
		for(int i=0; i<Sc; i++){
			for(int j=0; j<Sr; j++){
				if(Col[j].second == 'I')	cin >> tI;
				else	cin >> tR;
				In[i][j] = Info(Col[j].second == 'S', tI, tR);
				tI = 0; tR = "";
			}
		}
	}
	inline bool check(vector<Info>& x, Info l, string cmp, Info r){
		if(l.typ == 2)	l = x[Mp[toU(l.typ_str)]];
		if(r.typ == 2)	r = x[Mp[toU(r.typ_str)]];
		return chk(l, cmp, r);
	}
	inline Table& filter(Info a, string cmp, Info b){
		vector<vector<Info> > newInfo;
		newInfo.clear();
		for(auto x: In){
			Info l = a;
			Info r = b;
			if(check(x, l, cmp, r))
				newInfo.push_back(x);
		}
		Sc = newInfo.size();
		In = newInfo;
		return *this;
	}
	inline void print(vector<string> op){
		if(op[0] == "*"){
			printf("%d %d\n", Sr, Sc);
			for(auto& x: Col)
				printf("%s\n", x.first.c_str());
			for(auto& x: In){
				bool qq = 0;
				for(auto a: x){
					if(qq)	printf(" ");
					qq = true;
					if(a.typ == 0)	printf("%d", a.typ_int);
					else	printf("%s", a.typ_str.c_str());
				}
				printf("\n");
			}
		}
		else{
			printf("%d %d\n", (int)op.size(), Sc);
			for(auto& x: op)
				printf("%s\n", Col[Mp[toU(x)]].first.c_str());
			for(auto& x: In){
				bool qq = false;
				for(auto q: op){
					if(qq)	printf(" ");
					qq = true;
					Info a = x[Mp[toU(q)]];
					if(a.typ == 0)	printf("%d", a.typ_int);
					else	printf("%s", a.typ_str.c_str());
				}
				printf("\n");
			}
		}
	}
};
map<string, Table> tableMp;
Table mergeTable(Table& x, Table& y){
	Table ret;
	ret.Sr = x.Sr + y.Sr;
	ret.Sc = x.Sc * y.Sc;
	vector<Info> vec(0);
	for(int i=0; i<ret.Sr; i++)	vec.push_back(Info());
	for(int i=0; i<ret.Sc; i++)
		ret.In.push_back(vec);
	for(auto q: x.Col)	ret.Col.push_back(q);
	for(auto q: y.Col)	ret.Col.push_back(q);
	for(int i=0; i<ret.Sr; i++)
		ret.Mp[toU(ret.Col[i].first)] = i;
	for(int i=0; i<x.Sc; i++)
		for(int j=0; j<y.Sc; j++){
			int p = i * y.Sc + j;
			for(int k=0; k<x.Sr; k++)
				ret.In[p][k] = x.In[i][k];
			for(int k=0; k<y.Sr; k++)
				ret.In[p][k+x.Sr] = y.In[j][k];
		}
	return ret;
}

int T, N;
vector<string> symbols{"(", ")", "<=", ">=", "<", ">", "=", "<>", ","};
set<string> symbolList(symbols.begin(), symbols.end());
struct Tokens{
	string s = "";
	int typ = -1;
	bool over = false;
	inline Tokens& get(){
		s = ""; typ = -1;
		if(over)	return *this;
		char ch;
		do{
			ch = getchar();
		}while(ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n');
		if(ch == '\0' || ch == EOF){
			over = true;
			return *this;
		}
		else if(ch == '\"'){
			typ = 1;
			while(1){
				ch = getchar();
				if(ch == '\"')	break;
				if(ch == '\\')	ch = getchar();
				s += ch;
			}
		}
		else if(isdigit(ch)){
			typ = 0;
			s += ch;
			while(1){
				ch = getchar();
				if(!isdigit(ch))	break;
				s += ch;
			}
			ungetc(ch, stdin);
		}
		else if(isalpha(ch)){
			typ = 2;
			s += ch;
			while(1){
				ch = getchar();
				if(!isalpha(ch) && !isdigit(ch))	break;
				s += ch;
			}
			ungetc(ch, stdin);
		}
		else{
			typ = 3;
			s += ch;
			ch = getchar();
			if(symbolList.count(s + ch)){
				s += ch;
				ch = getchar();
			}
			ungetc(ch, stdin);
		}
		return *this;
	}
	inline Info status(){
		return Info(typ, (typ==0?atoi(s.c_str()):0), (typ==0?"":s));
	}
}Tkns;
vector<string> getOption;
vector<Info> whereOption;
vector<pair<string, bool> > orderOption;
vector<int> whereBracket;
Table currTable;
inline bool whereFilter(vector<Info>& x, int l, int r){
	while(whereBracket[l] == r)	++l, --r;
	bool ret = false;
	int u = r;
	if(whereBracket[u] != -1)	u = whereBracket[u];
	else	u = r - 2;
	if(u == r - 2){
		ret = currTable.check(x
				, whereOption[u]
				, whereOption[u+1].typ_str
				, whereOption[r]);
	}
	else	ret = whereFilter(x, u, r);
	while(u > l && whereOption[u-1] == Info(2, 0, "NOT"))
		ret ^= 1, --u;
	--u;
	if(u < l)	return ret;
	if(whereOption[u] == Info(2, 0, "AND"))
		return whereFilter(x, l, u-1) && ret;
	return whereFilter(x, l, u-1) || ret;
}
inline bool orderCmp(vector<Info>& l, vector<Info>& r){
	for(auto x: orderOption){
		Info L = l[currTable.Mp[toU(x.first)]];
		Info R = r[currTable.Mp[toU(x.first)]];
		if(L != R)	return (L < R) ^ x.second;
	}
	return false;
}
int main(){
	cin >> T;
	Tkns.get();
	bool ee = false;
	while(T--){
		if(ee)	printf("\n");
		ee = true;
		N = atoi(Tkns.s.c_str());
		tableMp.clear();
		for(int i=0; i<N; i++){
			Table t; t.read();
			tableMp[toU(t.name)] = t;
		}
		// SELECT
		Tkns.get();
		// [argv]
		getOption.clear();
		getOption.push_back(Tkns.get().s);
		while(Tkns.get().status() == Info(3, 0, ","))
			getOption.push_back(Tkns.get().s);
		// [from item]
		int Q = 0;
		vector<Table> tStk; tStk.clear();
		bool ww = true;
		while(1){
			string q = Tkns.get().s;
			int r = Tkns.typ;
			if((q == "(" || q == ")") && r == 3){
				Q += (q == "(" ? 1 : -1);
				continue;
			}
			if(q == "INNER" && r == 2 && !ww){
				Tkns.get();
				ww = true;
				continue;
			}
			if(q == "ON" && r == 2 && !ww){
				Tkns.get();
				Info a = Tkns.status();
				Tkns.get(); Tkns.get();
				Info b = Tkns.status();
				Table r = tStk.back(); tStk.pop_back();
				Table l = tStk.back(); tStk.pop_back();
				tStk.push_back(mergeTable(l, r).filter(a, "=", b));
				continue;
			}
			if(!ww)	break;
			tStk.push_back(tableMp[toU(q)]);
			ww = false;
		}
		currTable = tStk.back();
		if(Tkns.s == "WHERE"){
			whereOption.clear();
			bool ndO = true, lasN = false;
			int brk = 0;
			while(1){
				Tkns.get();
				whereOption.push_back(Tkns.status());
				if(Tkns.s == "(" && Tkns.typ == 3)	++brk, lasN = false;
				else if(Tkns.s == ")" && Tkns.typ == 3)	--brk, lasN = false;
				else if(Tkns.s == "NOT" && Tkns.typ == 2 && ndO)	lasN = true;
				else if(((Tkns.s == "AND" || Tkns.s == "OR"))
						&& Tkns.typ == 2 && !ndO)	ndO = true, lasN = false;
				else if(!ndO && !brk)	break;
				else{
					if(Tkns.typ != 3){
						Tkns.get();
						whereOption.push_back(Tkns.status());
					}
					ndO = lasN = false;
					Tkns.get();
					whereOption.push_back(Tkns.status());
				}
			}
			whereOption.pop_back();
			vector<vector<Info> > newInfo; newInfo.clear();
			whereBracket.clear();
			whereBracket.resize(whereOption.size(), -1);
			vector<int> whereStk; whereStk.clear();
			for(int i=0; i<(int)whereOption.size(); i++){
				if(whereOption[i] == Info(3, 0, "("))
					whereStk.push_back(i);
				if(whereOption[i] == Info(3, 0, ")"))
					whereBracket[i] = whereStk.back(),
					whereBracket[whereStk.back()] = i,
					whereStk.pop_back();
			}
			for(auto x: currTable.In){
				if(whereFilter(x, 0, whereOption.size()-1))
					newInfo.push_back(x);
			}
			currTable.Sc = newInfo.size();
			currTable.In = newInfo;
		}
		if(Tkns.s == "ORDER"){
			Tkns.get();
			orderOption.clear();
			while(1){
				string f; bool p = false;
				f = Tkns.get().s;
				Tkns.get();
				if(Tkns.s == "ASCENDING"){
					p = false; Tkns.get();
				}
				if(Tkns.s == "DESCENDING"){
					p = true; Tkns.get();
				}
				orderOption.emplace_back(f, p);
				if(Tkns.s != ",")	break;
			}
			sort(currTable.In.begin(), currTable.In.end(), orderCmp);
		}
		currTable.print(getOption);
	}
	return 0;
}
2021/7/16 19:47
加载中...