整理03 201912-201512

试题编号:201912-3
试题名称:化学方程式
#include<cstdio>
#include<cstring>
#include<cctype>
#include<iostream>
#include<string>
#include<sstream>
#include<map>
#include<vector>
using namespace std;

struct Elem{ //元素 
	string name; //名称 
	int num; //个数 
	Elem(string _name, int _num): name(_name), num(_num){}
};

int toNumber(string str, int &pos){ //从str的pos位置开始,得到一个数字 
	int num=0;
	while(isdigit(str[pos])){
		num=num*10+str[pos]-'0';
		pos++;
	}
	return num; 
} 

void calc(string &str, map<string, int> &mp){
	stringstream ss(str);
	string item;
	
	while(getline(ss, item, '+')){ //获取每一个化学式,如 32Ba((OH)2(CO3)2)3 
	 
		vector<Elem> arr; //存储化学式的分解序列, 如 Ba、(、(、O、H、)、(、C、O、)、) 
		int factor=1; //整个化学式的系数,默认为1 
		int i=0;
		//cout<<item[0]<<endl;
		if(isdigit(item[i])) 
		factor=toNumber(item,i); //计算化学式系数
		// cout<<factor<<" "<<item[i]<<endl;}
		 
		while(i<item.size()){
			if(isdigit(item[i])){ //处理数字
				int num=toNumber(item,i);
				if(arr[arr.size()-1].name==")"){ //序列最后一个元素是右括号 
					int j=arr.size()-1;
					arr[j].name="*"; //将右括号标记为*,忽略它的存在 
					while(arr[--j].name!="("){
						arr[j].num*=num;
					}
					arr[j].name="*"; //将左括号标记为*,忽略它的存在 
				}
				 
				else arr[arr.size()-1].num*=num;
			//	cout<<arr.size()<<" "<<arr[arr.size()-1].num<<endl; //序列最后一个元素是元素名称 
			}
			else if(item[i]=='('){ //处理左括号 
				arr.push_back(Elem("(", 0));  //括号加入到序列中
				i++;
			}
			else if(item[i]==')'){ //处理右括号
				arr.push_back(Elem(")", 0));  //括号加入到序列中
				if(!isdigit(item[i+1])) item.insert(i+1,"1"); //考虑到右括号右边可能不出现数字,补充底数1 
				i++;
			}
			else if(isupper(item[i])){ //处理大写字母 
				//得到元素名称 
				string name="";
				name+=item[i]; //大写字目 
				i++;
				if(islower(item[i])){ //小写字母 
					name+=item[i];
					i++;
				}
				arr.push_back(Elem(name,1)); //名称加入到序列中 
			}
		}
		
		for(int i=0; i!=arr.size(); ++i){ //将“元素->个数”保存到map中 
			if(arr[i].name=="*") continue; //忽略序列中括号的存在 
			mp[arr[i].name]+=arr[i].num*factor;
		}
		
	}
	
}

bool judge(map<string, int> &left, map<string, int> &right){ 
	if(left.size()!=right.size()) return false;
	for(map<string, int>::iterator it=left.begin(); it!=left.end(); ++it){
		if(right[it->first]!=it->second) return false;
	}
	return true;
}

int main(){
	int n;
	scanf("%d", &n);
	for(int i=0; i<n; ++i){
		map<string, int> left, right;
		string str, lstr, rstr;
		cin>>str;
		stringstream ss(str);
		getline(ss, lstr,'='); //得到等号左边的字符串 
		getline(ss, rstr); //得到等号右边的字符串 
	
		calc(lstr, left); //计算左字符串 
		calc(rstr, right);
		
		if(judge(left, right)) cout<<"Y"<<endl;
		else cout<<"N"<<endl; 
	}
	return 0;
}
试题编号:201909-3
试题名称:字符画

题解https://blog.csdn.net/best335/article/details/101296359 

#include<iostream>
#include<cstring>
#include<iomanip>
#include<vector>
using namespace std;
unsigned char C[1080][1920][3];//C[n][m][Pixel:RGB] 表示原图片在第n行m列的像素颜色 
inline unsigned char getPixel(const char&a,const char&b){//将16进制像素数转换为10进制的char 
	return char((isalpha(a)?(10+a-'a'):(a-'0'))*16+(isalpha(b)?(10+b-'a'):(b-'0')));
}
inline void outChar(const unsigned char&ch){//输出题意格式化的字符 
	cout<<"\\x"<<hex<<uppercase<<setw(2)<<int(ch);
}
inline void outStr(const string& str){//输出题意格式化的字符串 
	for(const char&c:str)outChar(c);
}
inline void outPixel(int i){//输出题意格式化的像素 
	vector<int> v;
	if(i==0)v.push_back(0);
	while(i>0) v.push_back(i%10),i/=10;//首先将数按位数分割 例:255 分割为 2、5、5三个数 
	for(i=v.size()-1;i>-1;--i) outChar(char('0'+v[i]));//输出每一位 
}
#include<fstream> 
int main(){
	int m,n,p,q,_B;// W H 
	ifstream cin("C:\\Users\\Isidore\\Desktop\\out.txt");
	cin>>m>>n>>p>>q,_B=p*q,cout.fill('0');
	string s;
	for(int i=0;i<n;++i){
		for(int j=0;j<m;++j){
			cin>>s;
			switch(s.size()){//将s统一格式化为 #abcdef 
				case 2://#a -> #aaaaaa 
					s=s+string(5,s[1]);
					break;
				case 4://#abc -> #aabbcc
					s="#"+string(2,s[1])+string(2,s[2])+string(2,s[3]);
					break;
			}
			for(int k=0;k<3;++k) C[i][j][k]=getPixel(tolower(s[k+k+1]),tolower(s[k+k+2]));
		}
	}
	int R=0,G=0,B=0,r=0,g=0,b=0;
	for(int i=0;i<n;i+=q){//共n/q个字符块行 
		for(int j=0;j<m;j+=p){//每字符块行共m/p段 
			R=0,G=0,B=0;//以下处理属于i行j段的字符块
			for(int k=i,nk=k+q;k<nk;++k)
				for(int l=j,nl=j+p;l<nl;++l)
					R+=C[k][l][0],G+=C[k][l][1],B+=C[k][l][2];
			R/=_B,G/=_B,B/=_B;//求平均值 
			if(!(R==r&&G==g&&B==b)){//如果与该行上一段的颜色不同 
				if(R==0&&G==0&&B==0)//如果与默认值相同 
					outStr(string(1,char(27))+"[0m");
				else//其他颜色处理 
					outStr(string(1,char(27))+"[48;2;"),outPixel(R),outChar(';'),outPixel(G),outChar(';'),outPixel(B),outChar('m');
				r=R,g=G,b=B;//记录上次的颜色 
			}
			outChar(' ');//输出 (n*m)/(p*q) 个空格 
		}
		if(R!=0||G!=0||B!=0) outStr(string(1,char(27))+"[0m");//行尾判断是否需要重置颜色 
		r=g=b=0;//重置默认颜色 
		outChar('\n');//输出n/q个回车 
	}
	return 0;
}
#include<bits/stdc++.h>
#include<string>
#include<vector>
#include<set> 
#include<map>
#include<iomanip>
#include<fstream>
using namespace std;
unsigned char C[1080][1920][3];
inline unsigned char getPixel(const char&a,const char&b){
	return char ((isalpha(a)?(10+a-'a'):(a-'0'))*16+(isalpha(b)?(10+b-'a'):(b-'0')));
	
}
inline void outChar(const unsigned char&ch){//hex十六进制 uppercase大写显示 
	cout<<"\\x"<<hex<<uppercase<<setw(2)<<int(ch);//setw(2) 对后面的设置宽度2 
}
inline void outStr(const string& str){
	//for(const char&c:str) outChar(c);
	int i=0;
	while(str[i]!='\0') outChar(str[i++]);
}
inline void outPixel(int i){
	vector<int> v;
	if(i==0) v.push_back(0);
	while(i>0) v.push_back(i%10),i/=10;
	for(i=v.size()-1;i>-1;--i) outChar(char('0'+v[i]));  
}
int main(){
	int m,n,p,q,_B;
	cin>>m>>n>>p>>q,_B=p*q,cout.fill('0');
	string s;
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			cin>>s;
			switch(s.size() ){
				case 2:s=s+string(5,s[1]);
				break;
				case 4:s="#"+string(2,s[1])+string(2,s[2])+string(2,s[3]);
				break;
			}
			for(int k=0;k<3;k++){//16进制->10进制 
				C[i][j][k]=getPixel(tolower(s[k+k+1]),tolower(s[k+k+2]));
			}
		}
	}
	int R=0,G=0,B=0,r=0,g=0,b=0;
	for(int i=0;i<n;i+=q){
		for(int j=0;j<m;j+=p){
			R=0,G=0,B=0;
			for(int k=i,nk=k+q;k<nk;++k){
				for(int l=j,nl=j+p;l<nl;++l){
					R+=C[k][l][0],G+=C[k][l][1],B+=C[k][l][2];
				}}
				R/=_B,G/=_B,B/=_B;
				if(!(R==r&&G==g&&B==b)){
					if(R==0&&G==0&&B==0)
					outStr(string(1,char(27))+"[0m");
					else{
						outStr(string(1,char(27))+"[48;2;"),outPixel(R),outChar(';'),outPixel(G),outChar(';'),outPixel(B),outChar('m');
					}
					r=R,g=G,b=B;
				}
			outChar(' ');//输出(n*m)/(p*q) 
		}
		if(R!=0||G!=0||B!=0) outStr(string(1,char(27))+"[0m");
		r=g=b=0;
		outChar('\n'); 
	} 
	return 0;
} 
试题编号:201903-3
试题名称:

损坏的RAID5

#include <bits/stdc++.h>
using namespace std;
#define SIZE 85000
bool isD[1001];
char datas[1001][SIZE], temp[9];
int main() {
    int n, s, l, m, pos;
    int value, disk_num, disk_pos;

    scanf("%d%d%d", &n, &s, &l);
    int t = 0, len = 0;
    for (int i = 0; i < l; i++) {
        scanf("%d%*c", &t);
        fgets(datas[t], SIZE, stdin);
 
        if (!len) len = strlen(datas[t]);
        isD[t] = true;
    }

    scanf("%d", &m);
    for (int i = 0; i < m; i++) {
        scanf("%d", &t);
        disk_num = (t / s) % n;  // 磁盘位置
        disk_pos = t / (s * n);  // 当前磁盘的条带位置
        value = (disk_pos - (n - disk_num - 1));
        if (value >= 0) disk_pos += value / n + 1;  // 条带位置纠正
        pos = ((disk_pos * s + t % s) << 3);
        if (pos + 8 > len) {
            puts("-");
            continue;
        }
        if (isD[disk_num]) {
            for (int k = 0; k < 8; k++) {
                putchar(datas[disk_num][pos + k]);
            }
            puts("");
            continue;
        }
        if (l == n - 1) {
            int k, ans = 0;
            for (int j = 0; j < n; j++) {
                if (isD[j]) {
                    for (int k = 0; k < 8; k++) temp[k] = datas[j][pos + k];
                    temp[8] = '\0';
                    sscanf(temp, "%x", &k);
                    ans ^= k;
                }
            }
            printf("%08X\n", ans);
        } else {
            puts("-");
        }
    }
    return 0;
}
试题编号:201812-3
试题名称:CIDR合并
#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
#include<vector>
#define ll long long
using namespace std;
struct Point  //ip是这个ip地址的十进制表示,ABCD分别是四个数字。
{
    ll ip,A,B,C,D;//len是前缀长度
    int len;
}Ip[100005];
bool cmp(Point a,Point b){//先按照ip再按照长度排序
    if(a.ip==b.ip){
        return a.len<b.len;
    }
    else return a.ip<b.ip;
}
bool check(Point a,Point b)//检验a和b能否进行a包含b的合并
{
    if(a.len>b.len)return 0;
    else{//判断长度到a前缀为止前缀是否相同
        if((a.ip>>(32-a.len))==(b.ip>>(32-a.len)))return 1;
        else return 0;
    }
}
bool check2(Point a,Point b)//判断是否a并b能够构成a前缀少一位的合并
{
    if(a.len!=b.len)return 0;
    if((a.ip>>(32-a.len+1))!=(b.ip>>(32-a.len+1)))return 0;
    if((a.ip>>(32-a.len))%2!=0)return 0;//提取a的第len位是不是0
    if((b.ip>>(32-b.len))%2==1)return 1;//提取b的第len位是不是1
}
Point sb(Point x){//sb函数返回为x的前缀少一位也就是a并b
    Point ans;
    ans=x;ans.len--;
    return ans;
}
int main()
{
    int n;
    cin>>n;
    char C[100005];
    for(int i=1;i<=n;i++){
        cin>>C;
        int l=strlen(C),num_d=0,num_x=0;
        for(int j=0;j<l;j++){//判断是哪一种ip前缀
            if(C[j]=='.')num_d++;
            if(C[j]=='/')num_x++;
        }
        ll a=0,b=0,c=0,d=0,Len=0,cnt=0,now=0;//不ll会爆int
        for(int j=0;j<l;j++){
            if(C[j]=='/'){now=0;cnt=100;continue;}
            if(C[j]=='.'){now=0;cnt++;continue;}
            now=now*10;now+=(C[j]-'0');
            if(cnt==0)a=now;if(cnt==1)b=now;
            if(cnt==2)c=now;if(cnt==3)d=now;
            if(j==l-1)Len=now;
        }//当作256进制乘起来
        Ip[i].A=a;Ip[i].B=b;Ip[i].C=c;Ip[i].D=d;
        Ip[i].ip=d+256*c+256*256*b+256*256*256*a;
        if(num_x)Ip[i].len=Len;
        else Ip[i].len=(num_d+1)*8;
 
    }
    vector<Point>v1;
    sort(Ip+1,Ip+1+n,cmp);//排序
    for(int i=1;i<=n;i++){//第一步合并
        int cnt=1;
        while(check(Ip[i],Ip[i+cnt])){cnt++;}
        v1.push_back(Ip[i]);
        i=i+cnt-1;
    }
    int lll=v1.size();//第二部合并
    for(vector<Point>::iterator it=v1.begin();it!=v1.end()-1;it++)
    {
        if(check2((*it),(*(it+1)))){
            v1.erase(it+1);
            (*it)=sb((*it));
            if(it!=v1.begin())it-=2;//题目说如果合并成功要回到这次合并的上一个
            else it--;//如果合并成功但是前边没有了
        }
    }
    lll=v1.size();//开心输出
    for(int i=0;i<lll;i++){
        cout<<v1[i].A<<"."<<v1[i].B<<"."<<v1[i].C<<"."<<v1[i].D<<"/"<<v1[i].len<<endl;
    }
 
}
/*
8
101.6.6.0/24
101.6.6.128/25
101.6.6/23
101/8
1/32
101.6.6.0
101.6
1
5
255.23.24.25/32
125.6.6.0/24
192.168.0.0/16
32.32.32.32/32
101.6.6.0/24
*/
试题编号:201809-3
试题名称:元素选择器

难点:后代选择器

#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
	int n, m;
	int prior[105]; //记录每个点的前驱  
	cin >> n >> m;
	string str[105];
	string biaoq[105], id[105]; //分别记录每个点的标签属性和id属性 
	getchar(); //吸收换行 
	int ceng[105]; //记录分层 
	for (int i = 1; i <= n; i++)
	{
		getline(cin, str[i]);
		ceng[i]=0;
	}
	ceng[0]=-1;//设根节点为-1 
	for (int i = 1; i <= n; i++)
	{
		//寻找.号;寻找id;截取标签并转大写 
		int j;
		for( j=0;j<(int)str[i].size();j++)
		{
			if(str[i][j]=='.') ceng[i]++;
			else break;
		 } 
		int pos = str[i].find(" ");//?
		if (pos == string::npos)
		{
			id[i] = "*"; //表示没有id属性 
		}
		else
		{
			id[i] = str[i].substr(pos + 1);
		}
		biaoq[i] = str[i].substr(j,pos-j);//截取标签 
		for (int j = 0; j < (int)biaoq[i].size(); j++)
		{
			biaoq[i][j] = toupper(biaoq[i][j]); //全部转化成大写 
		}
	}
	for(int i=1;i<=n;i++) //记录每个点的前驱 
	{
		for(int j=i;j>=0;j--)
		{
			if(ceng[i]>ceng[j])
			{
				prior[i]=j;
				break;//注意是当前的前驱 
			}
		}
	}
	string s;
	while (m--)
	{
		getline(cin, s);
		int len = 0;
		int pout[105];
		int pos = s.find(" ");
		if (pos == string::npos)  //处理id和标签选择器 
		{
			if (s[0] == '#')
			{
				for (int i = 1; i <= n; i++)
				{
					if (id[i] == s)
					{
						pout[len++] = i; //输出的编号 
					}
				}
			}
			else
			{
				for (int i = 0; i < (int)s.length(); i++)
				{
					s[i] = toupper(s[i]);
				}
				for (int i = 1; i <= n; i++)
				{
					if (biaoq[i] == s)
					{
						pout[len++] = i;
					}
				}
			}
		}
		else  //处理后代选择器 
		{
	
			int slen=0;//记录后代选择器中元素的个数 
		    s+=" ";//在结尾多添加一个空格,保证都截取到yuansu[]中 
			string yuansu[105];//提取元素选择器的每个单词
			string a="";//暂时保存 
			for(int j=0;j<(int)s.size();j++)
			{
				if(s[j]==' ') 
				{
					yuansu[slen]=a;
					a="" ,slen++;
				} 
				else a+=s[j];
			 } 
			 cout<<"yuansu="<<yuansu[slen-1]<<endl; 
			 for(int i=1;i<=n;i++)
			 {
			 	if(yuansu[slen-1][0]=='#') 
			 	{
			 		if(id[i]!=yuansu[slen-1]) continue;
				}
			 	else
			 	{
			 	 for(int j=0;j<(int)yuansu[slen-1].size();j++) 
				  yuansu[slen-1][j]=toupper(yuansu[slen-1][j]);
			 	  if(biaoq[i]!=yuansu[slen-1]) continue;
				}
			 	int cur=slen-2;//当前匹配到第几个 
			 	int node1=prior[i];//当前的结点 
			 	cout<<"cur="<<cur<<",node1="<<node1<<endl;
				 while(node1)
				 {
	
				 	if(yuansu[cur][0]=='#')
					 {
					 	if(id[node1]==yuansu[cur])
					 	{
					 	cur-=1;
						 }
					  } 
					  else
					  {
					  	for(int j=0;j<(int)yuansu[cur].size();j++) 
						  yuansu[cur][j]=toupper(yuansu[cur][j]);
					  	if(biaoq[node1]==yuansu[cur])
					  	{
					  		cur-=1;
						  }
					  }
					  node1=prior[node1];
					  if(cur==-1)
					  {
					  	pout[len++]=i;
					  	break;
					  }
				  } 
			 }
		}
		cout << len;
		for (int i = 0; i < len; i++)
		{
			cout<<" "<< pout[i];
		}
		cout << endl;
		memset(pout, 0, sizeof(pout));
		len = 0;
	}
    return 0;
}
/*
11 5
html
..head
....title
..body
....h1
....p #subtitle
....div #main
......h2
......p #one
......div
........p #one
p
3 6 9 11
#subtitle
1 6
h3
0
div p
yuansu=p
cur=0,node1=4
cur=0,node1=7
cur=0,node1=10
2 9 11
div div p
yuansu=p
cur=1,node1=4
cur=1,node1=7
cur=1,node1=10
1 11
*/

 

试题编号:201803-3
试题名称:URL映射

本题这里的解法只是用了字符串匹配技术,而且是按字符处理,并没有用到函数等,只是处理逻辑相对比较繁琐,需要有耐心。

程序说明

  匹配处理需要做2次,即2次调用函数match()。第一次只匹配,不输出结果;第二次匹配并输出结果;用参数来控制。

 

#include <iostream>
#include <ctype.h>
 
using namespace std;
 
const int N = 100;
string p[N], r[N], s;
 
bool match(string& s, string& t, bool flag)
{
    int lent = t.size();
    int lens = s.size();
    int ps = 0, pt = 0;
    while(ps < lens && pt < lent) {
        if(t[pt] == s[ps]) {
            ps++, pt++;
        } else {
            // 匹配<xxx>
            if(t[pt++] != '<')
                return false;
            if(flag)
                cout << ' ';
 
            if(t[pt] == 'i') {
                // 匹配<int>
                bool ok = false;
                while(s[ps] && isdigit(s[ps])) {
                    if(s[ps] != '0')
                        ok = true;
                    if(flag && ok)
                        cout << s[ps];
                    ps++;
                }
                if(!ok)
                    return false;
                pt += 4;
            } else if(t[pt] == 's') {
                // 匹配<str>
                bool ok = false;
                while(s[ps] && s[ps] != '/') {
                    ok = true;
                    if(flag)
                        cout << s[ps];
                    ps++;
                }
                if(!ok)
                    return false;
                pt += 4;
            } else if(t[pt] == 'p') {
                // 匹配<path>
                if(flag)
                    while(s[ps])
                        cout << s[ps++];
                return true;
            }
        }
    }
 
    return pt == lent && ps == lens;
}
 
int main()
{
    int n, m;
    cin >> n >> m;
    for(int i = 0; i < n; i++)
        cin >> p[i] >> r[i];
    for(int i = 0; i < m; i++) {
        cin >> s;
 
        bool flag = true;
        for(int j = 0; flag && j < n; j++)
            if(match(s, p[j], false)) {
                flag = false;
                cout << r[j];
                match(s, p[j], true);
            }
 
        if(flag)
            cout << "404";
        cout << endl;
    }
 
    return 0;
} 

201712-3 Crontab(没理清思路,没动手写)

 

/*20171203 - Crontab*/ 
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
using namespace std;
 
typedef long long LL;
int firstYear, lastYear;	// 开始与结束的年份
int range[5] = { 60, 24, 31, 12, 7 };
int days[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
string week[] = { "sun", "mon", "tue", "wed", "thu", "fri", "sat" },
mon[] = { "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec" };
map<string, int> mp;	// 保存各个英文缩写对应的值
vector<pair<LL, int> > ans;	// ans存放结果的 "时间,id" 对
 
// 如果是字母开头,一定是英文缩写,直接返回mp中对应的值;否则就是数字,按位累加即可
int strToI(string &str)
{
	if (isalpha(str[0]))
		return mp[str];
	int num = 0;
	for (int i = 0; i != str.size(); ++i)
		num = num * 10 + str[i] - '0';
	return num;
}
 
void dealMinus(set<LL> &tmp, string &str)
{
	for (int i = 0; i != str.size(); ++i)
		str[i] = tolower(str[i]);	// 不区分大小写
	size_t tp = str.find('-');
	if (tp == string::npos)
		tmp.insert(strToI(str));
	else{
		string left = str.substr(0, tp), right = str.substr(tp + 1);
		int l = strToI(left), r = strToI(right);
		for (int i = l; i <= r; ++i)
			tmp.insert(i);
	}
}
 
// 先分析s是否为"*",再分析',',最后分析'-'
void findValue(set<LL> &tmp, string &s, int j)
{
	if (s == "*"){
		for (int i = 0; i != range[j]; ++i)
			if (j == 2 || j == 3)	// 日期和月份是1开头的
				tmp.insert(i + 1);
			else
				tmp.insert(i);
		return;
	}
	s += ',';
	size_t pos = 0, next = s.find(',');
	string str;
	while (next != string::npos){
		str = s.substr(pos, next - pos);
		dealMinus(tmp, str);
		pos = next + 1;
		next = s.find(',', pos);
	}
}
 
// 分析y年m月d日是星期几,顺便排除一下不合法的日期比如11月31日
int getDay(int year, int month, int day)
{
	days[2] = 28;
	if (year % 4 == 0)
		days[2] = 29;
	if (day > days[month])	// 该日期不存在
		return -1;
 //1970年1月1日是星期4 
	int sum = 4, q = year - 1970;
	sum += q / 4 * 5 + q % 4;	// 每隔四年,sum应该+5
	if (q % 4 == 3)	// 这时说明 year-1 为闰年
		++sum;
	for (int i = 1; i != month; ++i)
		sum += days[i];
	sum += day - 1;
	return sum % 7;//周几 
}
 
// v[0] ~ v[3]不进行判断,只把tmp与pre中的内容组合起来,所有的判断放在v[4]中
void fillVector(vector<vector<LL> > &v, vector<LL> &tmp, int j, LL mul)
{
	if (j == 0)
		v[j] = tmp;
	else{
		vector<LL> &pre = v[j - 1];
		if (j != 4)
			for (int k = 0; k != tmp.size(); ++k)
				for (int l = 0; l != pre.size(); ++l)
					v[j].push_back(tmp[k] * mul + pre[l]);
 
		else{
			int judge[7] = { 0 };	// 用于判断一周中的每一天是否能够执行该命令
			for (int k = 0; k != tmp.size(); ++k)
				judge[tmp[k]] = 1;
			for (int l = 0; l != pre.size(); ++l){
				int month = pre[l] / 1000000, day = pre[l] / 10000 % 100;
				for (int year = firstYear; year <= lastYear; ++year){
					int dow = getDay(year, month, day);
					if (dow != -1 && judge[dow])	// 对每年的m月d日进行判断是否能够加入v[4]
						v[4].push_back(year * mul + pre[l]);
				}
			}
		}
	}
}
 
int main()
{
	for (int i = 0; i != 12; ++i)
		mp[mon[i]] = i + 1;
	for (int i = 0; i != 7; ++i)
		mp[week[i]] = i;
	int n;
	LL begin, end;
	cin >> n >> begin >> end;
	firstYear = begin / 100000000, lastYear = end / 100000000;
	vector<vector<string> > cron(n, vector<string>(6));	// 创建一个n*6的二维string数组cron
	for (int i = 0; i != n; ++i)
		for (int j = 0; j != 6; ++j)
			cin >> cron[i][j];
 
	// 对每一条指令,先分析有效的minute范围,存储在v[0],再分析有效的hour范围,将其与minute范围进行组合,存储在v[1]。
	// 以此类推,可以得出v[4]包含的即为最终的有效时间。
	for (int i = 0; i != n; ++i){
		vector<vector<LL> > v(5);
		LL mul = 1;
		for (int j = 0; j != 5; ++j){
			set<LL> valid;	// 因为题目的数据可能有 "3,2-4" 这种,所以用set存储去重复
			findValue(valid, cron[i][j], j);
			vector<LL> tmp;	// 为了方便使用之前版本的代码,这里新建一个vector保存valid中的数据
			for (set<LL>::iterator it = valid.begin(); it != valid.end(); ++it)
				tmp.push_back(*it);
			fillVector(v, tmp, j, mul);
			mul *= 100;
		}
		for (int j = 0; j != v[4].size(); ++j)
			ans.push_back(make_pair(v[4][j], i));
	}
 
	sort(ans.begin(), ans.end());
	for (vector<pair<LL, int> >::iterator it = ans.begin(); it != ans.end(); ++it)
		if (it->first >= begin && it->first < end)	// 不包含end
			cout << it->first << " " << cron[it->second][5] << endl;
}
试题编号:201709-3
试题名称:JSON查询(递归)

10 5
{
"firstName": "John",
"lastName": "Smith",
"address": {
"streetAddress": "2ndStreet",
"city": "NewYork",
"state": "NY"
},
"esc\\aped": "\"hello\""
}
firstName John
lastName Smith
address.streetAddress 2ndStreet
address.city NewYork
address.state NY
address {"streetAddress":"2ndStreet","city":"NewYork","state":"NY"}
esc\aped "hello"
firstName
STRING John
address
OBJECT
address.city
STRING NewYork
address.postal
NOTEXIST
esc\aped
STRING "hello" 

#include <iostream>
#include <string>
#include <map>
using namespace std;
 
map<string, string> mp;
void format(string &s)
{
	for (int i = 0; i < s.size(); ++i)
		// 如果遇到反斜杠,删除它并且跳过下个字符
		if (s[i] == '\\')
			s.erase(s.begin() + i);
}
 
// 这里做了一个假定:认为题目中":",",","{" 和 "}"只用于分隔,不会存在于json数据的其他位置
void deal(string &json, string &add){
	string key, value;
	for (int i = 0; i != json.size(); ++i)
		if (json[i] == '"'){
			int j = json.find(":", i + 1);
			key = json.substr(i + 1, j - i - 2);
			if (add == "")
				key = add + key;
			else
				key = add + "." + key;
 
			if (json[j + 1] == '"'){
				if (json.find(",", j + 1) != string::npos)
					i = json.find(",", j + 1);
				else
					i = json.size() - 1;
				value = json.substr(j + 2, i - j - 3);
				format(key);
				format(value);
			}
			else{
				// 括号匹配
				int count = 1;
				i = j + 2; // i从"{"的下一位开始
				while (count != 0){
					if (json[i] == '{')
						++count;
					else if (json[i] == '}')
						--count;
					++i;
				}
				value = json.substr(j + 1, i - j - 1);
				// else分支的value一定是对象
				// 要提供多层查询,用递归实现
				deal(value, key);
			}
			mp[key] = value;
			cout<<key<<" "<<mp[key]<<endl;
		}
}
 
int main()
{
	int n = 0, m = 0;
	cin >> n >> m;
	string s, json;
	// 将所有输入去空格,结合起来,赋给json进行处理
	string::iterator it;
	getline(cin, s);
	for (int i = 0; i != n; ++i){
		getline(cin, s);
		for (it = s.begin(); it != s.end();)
			if (isspace(*it))
				it = s.erase(it);
			else
				++it;
		json += s;
	}
//json={"firstName":"John","lastName":"Smith","address":{"streetAddress":"2ndStreet","city":"NewYork","state":"NY"},"esc\\aped":"\"hello\""}
 //cout<<"json="<<json<<endl; 
	string add;
	deal(json, add);
	for (int i = 0; i != m; ++i){
		cin >> s;
		if (mp.find(s) != mp.end()){
			if (mp[s][0] == '{')
				cout << "OBJECT" << endl;
			else
				cout << "STRING " << mp[s] << endl;;
		}
		else
			cout << "NOTEXIST" << endl;
	}
}

 

试题编号:201703-3
试题名称:Markdown
#include<bits/stdc++.h>
using namespace std;
vector<string> v;
int main(){
	string s,ss,v[101];
	int k=0;
	bool p=false,u=false;
	while(getline(cin,s)){
		ss=s;
		int pos=0,flag1=0;
		if((s.find("#",0) )!=-1){
			while((pos=s.find("#",0) )!=-1){
				flag1++;
				s.erase(pos,1);
			}
		string str;
		string f;
		f=flag1+'0';
		ss=ss.substr(flag1+1,ss.size()-1);
		str= "<h"+f+">"+ ss +"</h"+f+">";
		v[k]+=str ;
		k++;
	//	cout<<v[index++]<<endl;
		}
		else if(s[0]=='*'){
			if(!u){
				u=true;
				v[k]+="<ul>";
				k++;
			}
			s.erase(0,1);
			while(s[0]==' '){
				s.erase(0,1); 
			} 
			v[k]+="<li>";
			v[k]+=s;
			v[k]+="</li>";
			k++;
		} 
		else if(s.length() ==0){
			if(p){
				v[k-1]+="</p>";
				p=false;
			//	k++;
			}
			if(u){
				v[k]+="</ul>";
				u=false;
				k++;
			}
		}
		else {
			if(!p){
				p=true;
				v[k]+="<p>";
			}
			v[k]+=s;
			//v[k]+="</p>";
			k++;
		}
		
	}
		if(p){
				v[k-1]+="</p>";
				p=false;
			//	k++;
			}
			if(u){
				v[k]+="</ul>";
				u=false;
				k++;
			}
			string a,b;
		for(int i=0;i<k;i++){
			for(int j=0;j<v[i].length() ;j++){
				if(v[i][j]=='_'){
					v[i].erase(j,1);
					while(v[i][j]!='_'){
						a+=v[i][j];
						v[i].erase(j,1); 
					} 
					v[i].erase(j,1);
					v[i].insert(j,"</em>") ;
					
					v[i].insert(j,a) ;
					v[i].insert(j,"<em>") ;
					a="";
				}
				else if(v[i][j]=='['){
				
				v[i].erase(j,1);
				while(v[i][j]!=']') a+=v[i][j],v[i].erase(j,1);
				v[i].erase(j,2);
				while(v[i][j]!=')') b+=v[i][j],v[i].erase(j,1);
				v[i].erase(j,1);
				v[i].insert(j,"</a>");
				v[i].insert(j,a);
				v[i].insert(j,"\">");
				v[i].insert(j,b);
				v[i].insert(j,"<a href=\"");
				a=b="";
			
				}
			}
		}
		for(int i=0;i<k;i++){
		 cout<<v[i]<<endl; 
		} 
	return 0;
}
试题编号:201612-3
试题名称:权限查询
/*201612-3 权限查询*/ 
#include<bits/stdc++.h>
using namespace std;
struct Category{
	string name;
	int level;
};
struct Role{
	string roleName;
	struct Category roleCategory[11];
	int categoryNum;
};
struct User{
	string userName;
	struct Role userRole[11];
	int roleNum;
};
struct Category cate[101];
struct Role role[101];
struct User user[101];
int p,r,u,q;
struct Category getCategory(string s){
	int index;
	struct Category c;
	if((index=s.find(":",0))!=string::npos){
		c.name=s.substr(0,index);
		c.level=s.at(s.length() -1)-'0';
	}else{//没找到有等级的,直接赋值 
		c.name=s;
		c.level=-1;
	}
	return c;
}
int findRole(string roleName){
	for(int i=0;i<r;i++){
		if(role[i].roleName ==roleName){
			return i;
		}
	}
	return -1;
}
int findUser(string userName){
	for(int i=0;i<u;i++){
		if(userName==user[i].userName ){
			return i;
		}
	}
	return -1;
}
void findCategory(struct User oneUser,string quanxian){
	string quanxianName;
	int flag=0;
	int level,index,maxLevel=-1;
	if((index=quanxian.find(":",0))!=string::npos){
		quanxianName=quanxian.substr(0,index);
		level=quanxian.at(quanxian.length()-1)-'0';
	}else{
		quanxianName=quanxian;
		level=-1;
	}
	for(int i=0;i<oneUser.roleNum ;i++){
		struct Role onerole=oneUser.userRole [i];
		for(int j=0;j<onerole.categoryNum ;j++){
			struct Category oneCategory =onerole.roleCategory [j];
			if(quanxianName==oneCategory.name &&level==-1&&level==oneCategory.level ){
				flag=1;	
			}
			if(quanxianName==oneCategory.name &&level<=oneCategory.level&&level!=-1){
				flag=1;
			}
			if(quanxianName==oneCategory.name &&level==-1&&oneCategory.level!=-1){
				if(oneCategory.level >maxLevel){
					maxLevel=oneCategory.level;
					flag=2;
				}
			}
		}
	}
	if(flag==1){
		cout<<"true"<<endl;
	}
	else if(flag==2){
		cout<<maxLevel<<endl;
	}
	else if(flag==0){
		cout<<"false"<<endl;
	}
}
int main(){
	int i,j;
	string s;
	cin>>p;//输入权限 
	for( i=0;i<p;i++){
		cin>>s;
		cate[i]=getCategory(s);
	}
	cin>>r;//角色
	for(i=0;i<r;i++){
		cin>>role[i].roleName ;
		cin>>role[i].categoryNum ;
		for(j=0;j<role[i].categoryNum ;j++){
			cin>>s;
			role[i].roleCategory[j]=getCategory(s);
		}
	} 
	cin>>u;//输入用户
	for(i=0;i<u;i++){
		cin>>user[i].userName ;
		cin>>user[i].roleNum ;
		int index;
		for(j=0;j<user[i].roleNum ;j++){
			cin>>s;
			if((index=findRole(s))!=-1){
				user[i].userRole[j]=role[index];
			}
		}
	} 
	cin>>q;
	//开始查询
	while(q--){
		string name;
		string quanxian;
		cin>>name>>quanxian;
		int index;
		if((index=findUser(name))!=-1){
			struct User oneUser=user[index];
			findCategory(oneUser,quanxian);
		} else{
			cout<<"false"<<endl;
		}
	} 
	
	return 0;
} 
试题编号:201609-3
试题名称:炉石传说

 

#include<iostream>
using namespace std;
struct node{
	int health;
	int attack;
}n[2][18];

int p,q,t,ap,aq;
int a[2]={0};
int flag=0;
void del(int x,int p){
	for(int i=p;i<a[x];i++){
		n[x][i].attack=n[x][i+1].attack ;
		n[x][i].health =n[x][i+1].health  ;
	}
	n[x][a[x]].attack =0;
	n[x][a[x]].health =0;
	--a[x];
}
void summom(){
	cin>>p>>q>>t;
	++a[flag];
	for(int i=a[flag];i>p;i--){
		n[flag][i].health=n[flag][i-1].health;
		n[flag][i].attack =n[flag][i-1].attack ;
	}
		n[flag][p].health=t;
		n[flag][p].attack =q;
}
void attack(){
	cin>>ap>>aq;
	if(aq!=0){
		n[flag][ap].health-=n[!flag][aq].attack ;
		n[!flag][aq].health-=n[flag][ap].attack ;
		if(n[flag][ap].health<1){
			del(flag,ap);
		}
		if(n[!flag][aq].health<1){
			del(!flag,aq);
		}
	}else{
		n[!flag][aq].health-=n[flag][ap].attack ;//有疑问?? 
	}
}
void slove(){
	int num;
	if(n[0][0].health <1&&n[1][0].health >0){
		cout<<"-1"<<endl;
	}
	else if(n[0][0].health >0&&n[1][0].health <1){
		cout<<"1"<<endl;
	}else
	cout<<"0"<<endl;
	cout<<n[0][0].health <<endl;
	cout<<a[0];
	for(int i=1;i<=a[0];i++){
		cout<<" "<<n[0][i].health ;
	}
	cout<<endl;
	
	cout<<n[1][0].health <<endl;
	cout<<a[1];
	for(int i=1;i<=a[1];i++){
		cout<<" "<<n[1][i].health ;
	}
	cout<<endl;
}

int main(){
	int num;
	cin>>num;
	getchar();
	string str;
	n[0][0].health =30;
	n[1][0].health =30;
	//int flag=0;
	while(num--){
		cin>>str;
	
		if(str[0]=='s'){
			summom();
		}else if(str[0]=='e'){
			flag=!flag;
		}else if(str[0]=='a'){
			attack();
		}
		
	}slove();
	return 0;
}
试题编号:201604-3
试题名称:路径解析
#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;
	int pos;
	int p;
	string path,str;
	cin>>n>>path;
	getchar();
	while(n--){
		getline(cin,str);
		if(str.empty()){//str为空时 
			str=path;
		}
		else if(str[0]!='/'){
			str=path+"/"+str;
		}
	
		while((pos=str.find("/../"))!=-1){
			//cout<<"str="<<str<<endl;
			//cout<<"pos="<<pos<<endl;
			if(pos==0){
				str.erase(pos,3);
			}else{//反向查找,从pos-1往前找/的位置 
				p=str.rfind("/",pos-1);
				str.erase(p,pos+3-p);
			//str.erase(pos,3); 
			}
			
		}
		while((pos=str.find("/./"))!=-1){
			str.erase(pos,2);
		}
		while((pos=str.find("//"))!=-1){
			str.erase(pos,1);
		}
		if(str.size()>1&&str[str.size()-1]=='/'){// /d1/d2/ 
			str.erase(str.size()-1,str.size());// /d1/d2
		}
		cout<<str<<endl;
	}
	return 0;
}
试题编号:201512-3
试题名称:画图

 !

#include<bits/stdc++.h>
using namespace std;
char str[101][101];
int m,n,q;
void tianchong(int x,int y,char c){
if(x>=0&&x<m&&y>=0&&y<n){
	if(str[x][y]!='-'&&str[x][y]!='+'&&str[x][y]!='|'&&str[x][y]!=c){
		str[x][y]=c;
		tianchong(x+1,y,c);
		tianchong(x-1,y,c);
		tianchong(x,y+1,c);
		tianchong(x,y-1,c);
		}
	}else{
		return;
	}
}
int main(){
	cin>>m>>n>>q;//从下左上右看 
	for(int i=0;i<m;i++){
		for(int j=0;j<n;j++){
			str[i][j]='.';//初始化 
		}
	} 
	for(int i=0;i<q;i++){
	int flag,x1,x2,y1,y2;
		cin>>flag;
		if(flag==0){//画线 
			cin>>x1>>y1>>x2>>y2;
			if(x1==x2&&y1!=y2){
				if(y1>y2){
					int t;
					t=y1;
					y1=y2;
					y2=t;
				}
				for(int j=y1;j<=y2;j++){
					 if(str[x1][j]!='-'&&str[x1][j]!='+'){
						str[x1][j]='|';
					}else{
						str[x1][j]='+';
					} 
				}	
			}
			else{
				
				if(x1>x2){
					int t;
					t=x1;
					x1=x2;
					x2=t;
				}
				for(int j=x1;j<=x2;j++){
				
				 if(str[j][y1]!='+'&&str[j][y1]!='|'){
						str[j][y1]='-';
					//	cout<<str[j][y1]<<endl; 
					}	else{
						str[j][y1]='+';
					}
				}
			}
		}else{
			int x,y;
			char c; 
			cin>>x>>y>>c;
			tianchong(x,y,c);
		} 
	}
	for(int i=n-1;i>=0;i--){
		for(int j=0;j<m;j++){
			cout<<str[j][i];
		}
		cout<<endl;
	}
	return 0;
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值