ccf刷题记03
来源:互联网 发布:国债收益率升高知乎 编辑:程序博客网 时间:2024/05/29 05:53
今年9月份的最新题,还是有必要做一下的,然而网上搜不到题解,就比较坑了,没事,没做出来的题等下次ccf之前再补吧,看这段时间自己又能长进多少
201709-1打酱油
思路:这题一开始看到还有点懵,但这个样例的说明也太给了了吧,直接把做法就给出来说,分类讨论,瞬间秒做;
其实根据数据范围完全可以模拟的,单为了锻炼自己的计算能力,还是推了一下公式,这个能力还是需要的,毕竟之后无论什么题目似乎如果能用公式都比模拟好
#include <iostream>#include <cstdio>#include <algorithm>#include <vector>#include <cstring>#include <map>#include <cmath>#include <string>#include <queue>#include <stack>using namespace std;aconst int maxn = 1e5+10;int main(){ int n; while(scanf("%d",&n)!=EOF) { int sum = 0; /*while(n>=50) { n -= 50; sum += 7; }*/ int p1 = n/50; n %= 50; sum += p1*7; /*while(n>=30) { n -= 30; sum += 4; }*/ int p2 = n/30; n %= 30; sum += p2*4; /*while(n>=10) { n -= 10; sum += 1; }*/ int p3 = n/10; sum += p3; printf("%d\n",sum); } return 0;}
201709-2公共钥匙盒
思路:这题给的是每个老师的上课时间,拆分转化为钥匙交接的记录,按时间进行模拟就好了,建立数据结构存储时间,然后注意一下排序的原则就好了
最后,注意一下,不仅需要数组记录每个位置的钥匙,还需要单开一个数组记录钥匙的位置便于跟踪,其他就没什么了,30min2题,还好
#include <iostream>#include <cstdio>#include <algorithm>#include <vector>#include <cstring>#include <map>#include <cmath>#include <string>#include <queue>#include <stack>using namespace std;const int maxn = 2010;typedef struct EVENT{ bool borrow; int id; int time;}Event;Event e[maxn];int key[maxn];int keypos[maxn];bool cmp(const Event &a, const Event &b){ if(a.time<b.time) { return true; } else if(a.time==b.time) { if((!a.borrow)&&b.borrow) { return true; } else if((!a.borrow)&&(!b.borrow)) { if(a.id<b.id) { return true; } } } return false;}int main(){ int n,k; while(scanf("%d%d",&n,&k)!=EOF) { for(int i=1;i<=n;i++) { key[i] = i; keypos[i] = i; } for(int i=0;i<k;i++) { int keyid,keytime,keylast; scanf("%d%d%d",&keyid,&keytime,&keylast); e[2*i].borrow = true; e[2*i].id = keyid; e[2*i].time = keytime; e[2*i+1].borrow = false; e[2*i+1].id = keyid; e[2*i+1].time = keytime+keylast; } sort(e,e+2*k,cmp); for(int i=0;i<2*k;i++) { if(e[i].borrow) { key[keypos[e[i].id]] = 0; keypos[e[i].id] = 0; } else { for(int pos=1;pos<=n;pos++) { if(key[pos]==0) { key[pos] = e[i].id; keypos[e[i].id] = pos; break; } } } } printf("%d",key[1]); for(int i=2;i<=n;i++) { printf(" %d",key[i]); } printf("\n"); } return 0;}
201709-3JSON查询
思路:这题完全是字符串处理问题,用惯了scanf和字符串数组的我,对cin和getline真心手足无措,研究了好长时间
不过,这题确实信息量有点大,而且入手点也特别多,像冒号,引号,逗号都可以作为处理对象,而且后来发现任意处理一个结果都是一样的
但刚碰到的时候,就会思路一片混乱,不易冷静
有时候,一步步慢慢检查要比一起写完反而不知道哪里错了要好,不过还是细心吧,不出错总归是好的#include <iostream>#include <cstdio>#include <algorithm>#include <vector>#include <cstring>#include <map>#include <cmath>#include <string>#include <queue>#include <stack>using namespace std;const int maxn = 1e5+10;map<string,string> json;bool iskey;string dealstring(string key,string s){ if(s.empty()) { //cout << "empty " << endl; return key; } int slen = s.size(); for(int i=0;i<slen;i++) { //cout << key <<"*"<<s[i]<<"*"<<iskey<< endl; if(s[i] == ' ') { continue; } if(s[i] == '{') { //cout << "*3*" << endl; json[key] = "OBJECT"; iskey = true; } else if(s[i] == '}') { int len = key.size(); int str; for(str = len-1;str>=0;str--) { if(key[str] == '.') { break; } } if(str < 0) { key = ""; } else { key = key.substr(0,str); } } else if(s[i] == ',') { iskey = true; } else if(s[i] == ':') { iskey = false; } else if(s[i] == '"') { //cout << s[i] << s[i+1]<< endl; string nowstring; bool di = false; int j; for(j=i+1;j<slen;j++) { if(s[j] == '\\') { if(di) { di = false; nowstring += '\\'; } else { di = true; } } else if(s[j] == '"') { if(di) { di = false; nowstring += '"'; } else { break; } } else { nowstring += s[j]; } } if(iskey) { if(key=="") { key = nowstring; } else { key += '.' + nowstring; } } else { //cout << key << "*" << endl; json[key] = "STRING " + nowstring; int len = key.size(); int str; for(str = len-1;str>=0;str--) { if(key[str] == '.') { break; } } if(str < 0) { key = ""; } else { key = key.substr(0,str); } } i = j; } } return key;}int main(){ int n,m; //cout << json["hello"] << "***" << endl; /*if(json["hello"]=="") { cout << "***" << endl; }*/ ios::sync_with_stdio(false); while(cin >> n >> m) { /*char hh; hh = getchar(); cout << "^"<<hh << endl;*/ string temp; getline(cin,temp); json.clear(); /*cin.clear(); cin.sync();*/ iskey = false; string laststring = ""; while(n--) { getline(cin,temp); //cout << n << "###" <<temp<< endl; laststring = dealstring(laststring,temp); } while(m--) { //cout << m << "***" << endl; getline(cin,temp); if(json[temp] == "") { cout << "NOTEXIST" << endl; } else { cout << json[temp] << endl; } } } return 0;}/*10 5{"firstName": "John","lastName": "Smith","address": {"streetAddress": "2ndStreet","city": "NewYork","state": "NY"},"esc\\aped": "\"hello\""}firstNameaddressaddress.cityaddress.postalesc\aped*/
201709-4通信网络
思路:这一题乍一看,似乎不怎么困难,统计前驱和后继,对于每个点,其前驱的前驱必是其前驱,其后继的后继必是其后继,为了去重,用两个set处理吧
果然TLE了,虽然报的是WA,但根据时间发现应该是TLE的问题,只得到了可怜的30分
然而突然发现有向图set的速度似乎有点慢,而且双向边似乎要存两遍,处理两遍
于是,考虑退化,用最基础的数组存储,果然变快了,又过了一部分数据,得到50分了
于是,又想到数组和vector结合可以避免set,然而还是50分
然后似乎就真心没什么办法了,就50分吧,以后看看能不能拿满
#include <iostream>#include <cstdio>#include <algorithm>#include <vector>#include <cstring>#include <map>#include <cmath>#include <string>#include <queue>#include <stack>#include <set>using namespace std;const int maxn = 1010;/*set <int> pre[maxn];set <int> nex[maxn];set <int> connect[maxn];int main(){ int n,m; while(scanf("%d%d",&n,&m)!=EOF) { for(int i=1;i<=n;i++) { connect[i].clear(); nex[i].clear(); pre[i].clear(); connect[i].insert(i); pre[i].insert(i); nex[i].insert(i); } while(m--) { int p,q; scanf("%d%d",&p,&q); set<int> :: iterator it; for(it=pre[p].begin();it!=pre[p].end();it++) { pre[q].insert(*it); nex[*it].insert(q); connect[q].insert(*it); connect[*it].insert(q); } for(it=nex[q].begin();it!=nex[q].end();it++) { nex[p].insert(*it); pre[*it].insert(p); connect[p].insert(*it); connect[*it].insert(p); } } int sum = 0; for(int i=1;i<=n;i++) { if((int)(connect[i].size())==n) { sum++; } } printf("%d\n",sum); } return 0;}*//*bool connect[maxn][maxn];int main(){ int n,m; while(scanf("%d%d",&n,&m)!=EOF) { memset(connect,false,sizeof(connect)); for(int i=1;i<=n;i++) { connect[i][i] = true; } while(m--) { int p,q; scanf("%d%d",&p,&q); for(int i=1;i<=n;i++) { if(connect[i][p]) { connect[i][q] = true; } if(connect[q][i]) { connect[p][i] = true; } } } int sum = 0; for(int i=1;i<=n;i++) { int tempsum = 0; for(int j=1;j<=n;j++) { if(connect[i][j]||connect[j][i]) { tempsum++; } } if(tempsum == n) { sum++; } } printf("%d\n",sum); } return 0;}*/vector <int> pre[maxn];vector <int> nex[maxn];bool connect[maxn][maxn];int main(){ int n,m; while(scanf("%d%d",&n,&m)!=EOF) { memset(connect,false,sizeof(connect)); for(int i=1;i<=n;i++) { connect[i][i] = true; nex[i].clear(); pre[i].clear(); pre[i].push_back(i); nex[i].push_back(i); } while(m--) { int p,q; scanf("%d%d",&p,&q); vector<int> :: iterator it; for(it=pre[p].begin();it!=pre[p].end();it++) { if(!connect[*it][q]) { connect[*it][q] = true; pre[q].push_back(*it); nex[*it].push_back(q); } } for(it=nex[q].begin();it!=nex[q].end();it++) { if(!connect[p][*it]) { connect[p][*it] = true; nex[p].push_back(*it); pre[*it].push_back(p); } } } int sum = 0; for(int i=1;i<=n;i++) { int tempsum = 0; for(int j=1;j<=n;j++) { if(connect[i][j]||connect[j][i]) { tempsum++; } } if(tempsum == n) { sum++; } } printf("%d\n",sum); } return 0;}
201709-5 除法
思路:最后一题,线段树题,然而我对于线段树还是比较茫然的,还是试试骗分吧
开始了骗分之路,首先,强行模拟吧,利用第一个条件l=r,由区间变单点
后来发现只是操作1区间变单点,于是改用树状数组
然而还是0分,猛然发现,结果可能超long long,于是20分到手
于是,想再做个遍历,说不定又能骗一点分呢
果然,50分到手,最终ccf400+,还行,看来有些时候,还是变换形态吧,加油,fighting
#include <iostream>#include <cstdio>#include <algorithm>#include <vector>#include <cstring>#include <map>#include <cmath>#include <string>#include <queue>#include <stack>using namespace std;const int maxn = 1e5+10;long long a[maxn],c[maxn];int lowbit(int x)//对应管辖区域{return x&-x;}long long sum(int i)//求数组c前i项和{long long s=0;while(i>0){s+=c[i];i-=lowbit(i);}return s;}void modify(int i,long long val,int n)//将第i个元素加上val,n为数组大小{while(i<=n){c[i]+=val;i+=lowbit(i);}}int main(){ //cout<<"1"<<endl; //cout<<"2"<<endl; int n,m; while(scanf("%d%d",&n,&m)!=EOF) { memset(c,0,sizeof(c)); for(int i=1;i<=n;i++) { scanf("%lld",&a[i]); modify(i,a[i],n); } while(m--) { int p; scanf("%d",&p); if(p==1) { int l,r; long long v; scanf("%d%d%lld",&l,&r,&v); //cout << l << "*"<< r << "*" << v << endl; for(int i=l;i<=r;i++) { //cout << "###" << endl; if(a[i]%v==0) { a[i] /= v; long long di = a[i] - a[i]*v; modify(i,di,n); } /*for(int j=1;j<=n;j++) { cout << sum(j) << " "; } cout << endl;*/ } } else { int l,r; scanf("%d%d",&l,&r); printf("%lld\n",sum(r) - sum(l-1)); /*for(int i=1;i<=n;i++) { cout << sum(i) << " "; } cout << endl;*/ } } } return 0;}
最后两题,这段时间确实是没时间再补了,以后有时间再看看吧
文章地址:http://blog.csdn.net/owen_q/article/details/78229956
- ccf刷题记03
- ccf刷题记01
- ccf刷题记02
- ccf刷题记04
- ccf刷题记终级版01
- OI刷题记录
- LeetCode刷题记
- OI刷题记录~
- leetcode刷题记录
- 刷题记录
- LeetCode刷题记
- LeetCode刷题记 2
- LeetCode刷题记 3
- 6.22刷题记录
- 7.26-刷题记录
- hdu 刷题记录
- 面试刷题记录
- 每日刷题记录
- Oracle中scott账户的解锁
- 浅谈nginx内存池(一)
- Redis笔记(2)-配置
- SPFA———【模板】单源最短路径、租用游艇
- 选择(select)和冒泡(bubble)排序
- ccf刷题记03
- recyclerview的博客网址需要的权限
- 移动架构20_策略模式
- angular从json串里获取数据赋值ul和table
- Django其他(站点、列表、上传
- 2017初赛预备
- 我的Java课程学习1——Hello World
- 获取windows哈希值
- 一个项目:项目信息分页显示、查询