选拔考试
T1:
小K手中有n张牌,每张牌上有一个一位数的数,这个字数不是0就是5。小K从这些牌在抽出任意张(不能抽0张),排成一行这样就组成了一个数。使得这个数尽可能大,而且可以被90整除。
样例:
Input:
4
5 0 5 0
Output:
0
思路:
被90整除即同时被9和10整除,被10整除则至少有一个0,被9整除则5的个数为9的倍数,简单题
直接上代码:
#include<cstdio> #include<cstring> #include<iostream> #define CL(X,N) memset(X, N, sizeof(X)) #define LL long long using namespace std; const int maxn=1e3+10; int a[maxn], n; int cnt5=0, cnt0=0; inline void _init() { freopen("zaf.in", "r", stdin); freopen("zaf.out", "w", stdout); } int main() { _init(); scanf("%d", &n); for(int i=0; i<n; i++) { scanf("%d", a+i); if(a[i]==5) cnt5++; if(a[i]==0) cnt0++; } if(!cnt0) { printf("-1"); return 0; } int ls=cnt5/9; if(ls){ for(int i=0; i<ls*9; i++) printf("5"); for(int i=0; i<cnt0; i++) printf("0"); } else printf("0"); return 0; }
这么简单,不想打注释
T2:
现在有一块玻璃,是长方形的(w 毫米× h 毫米),现在要对他进行切割。切割的方向有两种,横向和纵向。每一次切割之后就会有若干块玻璃被分成两块更小的玻璃。在切割之后玻璃不会被移动。
现在想知道每次切割之后面积最大的一块玻璃是多少。
样例:
Input:
4 3 4
H 2
V 2
V 3
V 1
Output:
8
4
4
2
样例解释:
对于第四次切割,下面四块玻璃的面积是一样大的。都是2
思路:
标准思路:倒过来处理,如果当前位置x是割线,那么 H[x].l表示该割线左面那条割线的位置, H[x].r表示该割线右面那条割线的位置, H[i].val表示该割线与左面那条割线之间的长度, 这样每次增加割线倒过来之后就相当于删除割线, 当然每次删除只要O(1)更新这条割线左右两边割线的值就好,每次答案就是max(H[i].val)*max(V[i].val),i∈[0,w(h)] ,总复杂度:O(n)
当时思路:
为了避免TLE,先将操作存下来,并标记先后(将上下左右边界也存进去,id设为0),按位置排序后,正向跑for并记录最大的当前宽度和高度,依次输出结果(其实差不多)
燃鹅,令我懵逼的是,有人每读入一个操作就sort一次,然后跑for,居然也没TLE(一定是数据太水)
然后放代码吧:
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #define CL(X,N) memset(X, N, sizeof(X)) #define LL long long using namespace std; const int maxn=2e5+10; int w, h, n; struct cut { LL x; int id; cut(){} cut(LL _x, int _id) : x(_x), id(_id) {} }wl[maxn], hl[maxn]; bool cmp(cut a, cut b) { return a.x<b.x; } inline void _init() { freopen("cut.in", "r", stdin); freopen("cut.out", "w", stdout); } int cnth=2, cntw=2; int main() { _init(); scanf("%d%d%d", &w, &h, &n); wl[0]=cut(0, 0); wl[1]=cut(w, 0); hl[0]=cut(0, 0); hl[1]=cut(h, 0); //初始化 for(int i=1; i<=n; i++) { char cmd[2]; LL x; scanf("%s", cmd); //把'\n'吞掉 scanf("%d", &x); if(cmd[0]=='H') { hl[cnth++]=cut(x, i); } else if(cmd[0]=='V') { wl[cntw++]=cut(x, i); } } sort(wl, wl+cntw, cmp); sort(hl, hl+cnth, cmp); for(int i=1; i<=n; i++) { LL answ=0, ansh=0; LL lastw=0, lasth=0; for(int j=1; j<cntw; j++) { if(wl[j].id>i) continue; answ=max(answ, wl[j].x-lastw); //计算最大宽度 lastw=wl[j].x; } for(int j=1; j<cnth; j++) { if(hl[j].id>i) continue; ansh=max(ansh, hl[j].x-lasth); //最大高度 lasth=hl[j].x; } printf("%lld\n", answ*ansh); } return 0; }
这是我自己的代码,就不放标程了...
T3:
小H是个善于思考的学生,现在她又在思考一个有关序列的问题。
她的面前浮现出一个长度为n的序列{ai},她想找出一段区间[L, R](1 <= L <= R <= n)。
这个特殊区间满足,存在一个k(L <= k <= R),并且对于任意的i(L <= i <= R),ai都能被ak整除。这样的一个特殊区间 [L, R]价值为R - L。
小H想知道序列中所有特殊区间的最大价值是多少,而有多少个这样的区间呢?这些区间又分别是哪些呢?你能帮助她吧。
【输入格式】
第一行,一个整数n.
第二行,n个整数,代表ai.
【输出格式】
第一行两个整数,num和val,表示价值最大的特殊区间的个数以及最大价值。
第二行num个整数,按升序输出每个价值最大的特殊区间的L.
样例:
Input:
5
4 6 9 3 6
Output:
1 3
2
【数据范围】
30%: 1 <= n <= 30 , 1 <= ai <= 32.
60%: 1 <= n <= 3000 , 1 <= ai <= 1024.
80%: 1 <= n <= 300000 , 1 <= ai <= 1048576.
100%: 1 <= n <= 500000 , 1 <= ai < 2 ^ 31.
思路:
标准思路:
30% :暴力枚举判断。O(n^4)。
60% :特殊区间的特点实际上就是区间最小值等于这个区间的GCD,于是暴力或递推算出每个区间最小值与GCD。而对于最大价值,可以通过二分来进行求解。复杂度O(n ^ 2)。
100%:在60%的基础上,最小值与GCD都使用RMQ算法来求解,对于这道题推荐使用ST表。最大价值仍然使用二分。复杂度O(nlogn)。
当时思路:
当看到数据范围时,我真的方了,说真的,当时就觉得跑一个for已经极限了,跑两个for就该TLE了,GCD更容易TLE(还要判断区间GCD,真不敢写),燃鹅,我还是毅然决然的暴力(想不到更好的方法了),最后写了一个O(n^2)的,真的听天由命了
但是,我居然过了(hahahaha...),真心高兴
然后上代码:
#include<cstdio> #include<cstring> #include<iostream> #define CL(X,N) memset(X, N, sizeof(X)) #define LL long long using namespace std; const int maxn=5e5+10; int n; int a[maxn]; int l[maxn]={0}, maxlen=0, num=0; int vis[maxn]; inline void _init() { freopen("pair.in", "r", stdin); freopen("pair.out", "w", stdout); } int main() { //_init(); CL(vis, -1); scanf("%d", &n); for(int i=1; i<=n; i++) { scanf("%d", a+i); } for(int i=1; i<=n; i++) { int ll=i, rr=i; while(ll>1 && !(a[ll-1]%a[i])) ll--; while(rr<n && !(a[rr+1]%a[i])) rr++; if(rr-ll>maxlen) { num=0; maxlen=rr-ll; } if(rr-ll==maxlen && vis[ll]!=maxlen) { l[num++]=ll; vis[ll]=maxlen; } } printf("%d %d\n", num, maxlen); for(int i=0; i<num; i++) printf("%d ", l[i]); return 0; }
题目就先到这里了
还有一件事,inline内联函数后是需要返回值的,如void,不知为毛_init()前不加void在我的本地也能过编译,最后提交后编译失败,把我吓的...还好允许改回来,还是得了分
这个神奇的本地通过真心迷...(不知道有没有人和我一样)