牛客IOI周赛18-普及组(A-C)
A、数字计数
显然水题
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def main(): n = int(input()) a_li = list(set(map(int,input().split()))) a_li.sort() print(a_li[-1] - a_li[-2],a_li[-1] - a_li[1],a_li[-2] - a_li[1],a_li[-2] - a_li[0]) if __name__ == "__main__": main()
B、数颜色
一开始想暴力,想了想可能会超时,然后想到了为什么不枚举颜色,求出可能出现的区间个数呢,而我写的算法是 颜色个数*n*(n+1)/2 - 某颜色不可能出现的区间个数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int NMAX = 2e5 + 10; const int MOD = 1e9 + 7; int pre[NMAX]; int main(int argc, char const *argv[]) { int n , a; scanf("%d",&n); ll ans = 0; for(register int i = 1;i <= n;i++) { scanf("%d",&a); if(!pre[a]) ans += n * (n + 1) / 2; ans -= (i - pre[a] - 1) * (i - pre[a]) / 2; pre[a] = i; } for(register int i = 1;i <= 1000;i++) { if(!pre[i]) continue; ans -= (n + 1 - pre[i] - 1) * (n + 1 - pre[i]) / 2; } printf("%lld\n",ans ); return 0; }
C、智斗恶龙
bfs, 但vised不能每次都全部进行清零,只对修改过的vised数组进行清零
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int NMAX = 1e3 + 10; const int MOD = 1e9 + 7; ll mmap[NMAX][NMAX] , gold[NMAX*NMAX]; bool vised[NMAX][NMAX]; pair<int,int>vec[NMAX*NMAX]; struct Node{ int x,y,step; Node(int x,int y,int step):x(x),y(y),step(step){}; }; int tot = 0 , cot = 0; int dir[4][2] = {-1,0,1,0,0,1,0,-1}; int main(int argc, char const *argv[]) { int t; int n , m , sx , sy , d , x; scanf("%d",&t); set<ll>s; while(t--) { s.clear(); cot = tot = 0; scanf("%d%d%d%d%d%d",&n,&m,&sx,&sy,&d,&x); for(register int i = 1;i <= n;i++) for(register int j = 1;j <= m;j++) scanf("%lld",&mmap[i][j]); if(mmap[sx][sy] == -1) { puts("no"); continue; } queue<Node>q; if(mmap[sx][sy]) s.insert(mmap[sx][sy]); q.push(Node(sx,sy,0)); vised[sx][sy] = true; vec[tot++] = make_pair(sx,sy); while(!q.empty()) { Node now = q.front();q.pop(); for(register int i = 0;i < 4;i++) { int next_x , next_y; next_x = now.x + dir[i][0]; next_y = now.y + dir[i][1]; if(next_x < 1 || next_x > n || next_y < 1 || next_y > m || mmap[next_x][next_y] == -1|| vised[next_x][next_y] || now.step >= d) continue; vec[tot++] = make_pair(next_x,next_y); vised[next_x][next_y] = true; q.push(Node(next_x,next_y,now.step + 1)); if(mmap[next_x][next_y]) s.insert(mmap[next_x][next_y]); } } while(tot) { int next_x = vec[tot-1].first , next_y = vec[tot-1].second; vised[next_x][next_y] = false; tot--; } if(s.size() < x) puts("no"); else { for(set<ll>::iterator it = s.begin(); it != s.end();it++) gold[++cot] = *it; ll ans = gold[cot] - gold[1]; for(register int i = 1;i <= cot - x + 1;i++) ans = min(ans , gold[i + x - 1] - gold[i]); printf("%lld\n",ans ); } } return 0; }