CCF CSP第十一次认证考试 20170917

第一题: 买酱油,买五瓶送两瓶,买三瓶送一瓶。10元/瓶。给出钱数,问最多能买多少瓶酱油。

第二题:教师取放钥匙,结构体排序,重载运算符。

第三题:文件操作,字符串处理,查询。

第四题:有向图的搜索。能达到点v的点数 + 点v可达到的点数 == 总点数n - 1。询问有多少个这样的点。暴力深搜每个点,记录可达信息

第五题:听说特判1能得八十分。用树状数组+特判1优化就满分了。好像还可以优雅地暴力解题,分块+莫队。但我不会。


第三题把读到的信息去掉所有空格,就是一个串。对于要查询的字符串例如address,变成 键"address": 这样就不会和值中的address重了。只得了60分这题。 


第一题:(100)

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <list>
#include <cmath>
using namespace std;
int main()
{
	//ios::sync_with_stdio(false);
	int n;
	while(~scanf("%d", &n)) {
		n /= 10;
		int cnt = (n / 5) * 7;
		n %= 5;
		cnt += (n / 3) * 4;
		n %= 3;
		cnt += n;
		printf("%d\n", cnt);
	}
	
	return 0;
}


第二题:(100)

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <list>
#include <cmath>
using namespace std;
const int N = 1007;
struct Node {
	int id, t, fg; //t时间点, fg: 0还钥匙,1取钥匙 
	Node(int id = 0, int t = 0, int fg = 0):id(id), t(t), fg(fg){}
	bool operator < (const Node &tmp) const {
		return t == tmp.t ? (fg == tmp.fg ? id < tmp.id : fg < tmp.fg) : t < tmp.t;
	}
}a[N << 1];
int v[N];
int main()
{
	//ios::sync_with_stdio(false);
	int n, k;
	while(~scanf("%d%d", &n, &k)) {
		int id, st, len, cur = 0;
		for(int i = 1; i <= k; ++i) {
			scanf("%d%d%d", &id, &st, &len);
			a[cur++] = Node(id, st, 1);
			a[cur++] = Node(id, st + len, 0);
		}
		for (int i = 1; i <= n; ++i) v[i] = i;
		sort(a, a + cur);
//		for (int i = 0; i < cur; ++i) {
//			printf("%d %d %d\n", a[i].t, a[i].id, a[i].fg);
//		}
		for (int i = 0; i < cur; ++i) {
			if(a[i].fg == 1) {
				for (int pos = 1; pos <= n; ++pos) if(v[pos] == a[i].id) {
					 v[pos] = 0; 
					 break;
				}
			}
			else {
				for (int pos = 1; pos <= n; ++pos) if(v[pos] == 0) {
					v[pos] = a[i].id;
					break;
				}
			}
		}
		for(int i = 1; i <= n; ++i) {
			printf("%d%c", v[i], " \n"[i==n]);
		}
	}
	
	return 0;
}

第三题:(60)

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <list>
#include <cmath>
using namespace std;
const int N = 107;
string dup(string str) {
	for (string::iterator it = str.begin(); it != str.end(); ++it) {
		if(*it == ' ') str.erase(it--);
	}
	return str;
}
string add(string str) {
	string res = "";
	int len = str.length();
	for (int i = 0; i < str.length(); ++i) {
		if(str[i] == '\\' || str[i] == '\"') res += '\\';
		res += str[i];		
	}
	return res;
}
int main()
{
	ios::sync_with_stdio(false);
	int n, m;
	while(cin >> n >> m) {
		string tmp, s = "", t;
		cin.get();
		for (int i = 0; i < n; ++i) {
			getline(cin, tmp); s += tmp;
		}
		s = dup(s); //cout << s << endl << s.length() << endl;
		int len = s.length();
		while(m-- > 0) {
			cin >> t; 
			t = add(t);
		///*	
			t = '\"' + dup(t) + "\":";// cout << t << endl;
			string res = "";
			int found = (int) s.find(t), i;
			if(found == -1) {cout << "NOTEXIST" << endl;}
			else {
				found += t.length();
				//cout << found << " " << s[found] << endl;			
				for (i = found; i < len; ++i) {
					if(s[i] == '}' && i != len - 1) {
						found = (int)s.find(t, i);
						//cout << i << " " << s[i] << endl;
						if(found == -1) {cout << "NOTEXIST" << endl; }
						else {
							found += t.length() + 1;
							if(s[found] == '{') cout << "OBJECT" << endl;
							else {   	
								cout << "STRING ";
								while(s[found] != '\"') cout << s[found++];
								cout << endl;//error
							}
						} 
						break;
					}
					else if(s[i] == '{'){
						break;
					}					
				}
				if(i >= len || s[i] == '{') {
					//cout << found << " " << s[found] << endl;
					if(s[found] == '{') cout << "OBJECT" << endl;
					else {
						cout << "STRING ";
						for(int i= found + 1; i < len; ++i) {
							if(s[i] == '\\') cout << s[++i];
							else if(s[i] == '\"') break;
							else cout << s[i];
						}
						cout << endl;
					}
				} 
//				else {
//					cout << i << " " << s[i] << endl;
//				}
			}
		//*/
		}
	}
	
	return 0;
}

第四题:(100)

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
const int N = 1007;
vector<int> e[N]; //动态数组邻接表存图
bool mp[N][N]; //mp[i][j] i 到 j是否通 
bool vis[N];
void dfs(int u, int cur) {
	vis[u] = 1;
	mp[u][cur] = mp[cur][u] = 1;
	for (int i = e[u].size() - 1; i >= 0; --i) {
		int v = e[u][i];
		if (!vis[v])
			dfs(v, cur);
	}
}
int main()
{
	int n, m, cnt = 0;
	scanf("%d%d", &n, &m);
	for (int i = 0; i<m; ++i) {
		int u, v;
		scanf("%d%d", &u, &v);
		e[u].push_back(v);
	}
	for (int i = 1; i <= n; ++i) {
		memset(vis, 0, sizeof vis);
		dfs(i, i);
	}
	for (int i = 1; i <= n; ++i) {
		bool fg = true;;
		for (int j = 1; j <= n; ++j) {
			if (mp[i][j] == 0) {
				fg = false;
				break;
			}
		}
		cnt += fg;
	}
	printf("%d", cnt);

	return 0;
}

第五题:

#include <cstdio>
#include <cstring>

using namespace std;
const int N = 1e6 + 7;
typedef long long LL;
LL bit[N];
int n, m, a[N];
inline int lowbit(int x) {
    return x & -x;
}
void add(int pos, int val) {
    for (int i = pos; i <= n; i += lowbit(i))
        bit[i] += val;
}
LL sum(int x) {
    LL res = 0;
    for (int i = x; i > 0; i -= lowbit(i)) {
        res += bit[i];
    }
    return res;
}

int main()
{
    while(~scanf("%d%d", &n, &m)) {
        memset(bit, 0, sizeof bit);
        for (int i = 1; i <= n; ++i) {
            scanf("%d", a + i);
            add(i, a[i]);
        }
        while(m-- > 0) {
            int opt, l, r, val;
            scanf("%d", &opt);
            if(opt == 1) {
                scanf("%d%d%d", &l, &r, &val);
                if(val == 1) continue; //虽有整数都是1的倍数,优化
                for(int i = l; i <= r; ++i) if(a[i] >= val && a[i] % val == 0) {
                        add(i,a[i] / val - a[i]);
                        a[i] /= val;
                }
            }
            else if(opt == 2) {
                scanf("%d%d", &l, &r);
                printf("%lld\n", sum(r) - sum(l - 1));
            }
        }
    }

    return 0;
}




评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值