F.排列计算
思路:
一个很显然的思路就是我们希望出现次数多的位置的数尽可能的大。
所以我们需要统计每个位置出现的次数,因为每次是一个区间操作,暴力可能会超时,我们考虑用差分。
差分完后求一下前缀和就是每个位置出现的次数了。
然后我们把每个位置出现次数和下标保存起来,按照出现次数排序,然后从 到
从大到小去构造这个序列。
然后按照原位置求一下前缀和再计算一下输入的区间的值就行了。
可能会比较繁琐,我看到有更好的做法。
代码:
#include using namespace std; typedef long long int ll; const int maxn = 2e5 + 10; int dif[maxn]; ll sum[maxn]; void add(int l,int r,int v){ dif[l]++;dif[r + 1]--; } struct node{ int pos,v; node(){} node(int a,int b):pos(a),v(b){} }; bool cmp(node a,node b){ return a.v > b.v; } bool cmp2(node a,node b){ return a.pos < b.pos; } void solved(){ int n,m;cin>>n>>m; vectorins; for(int i = 1; i <=m ;i++){ int l,r;cin>>l>>r; ins.push_back(node(l,r)); add(l,r,1); } for(int i = 1; i <= n; i++){ dif[i] += dif[i - 1]; } vectorst; for(int i = 1; i<= n; i++)st.push_back(node(i,dif[i])); sort(st.begin(),st.end(),cmp); int tot = n; for(int i = 0; i < n; i++){ st[i].v = tot--; } sort(st.begin(),st.end(),cmp2); for(int i = 1; i <= n; i++){ sum[i] = sum[i - 1] + st[i - 1].v; // cout<<st[i - 1].v<<" "; } ll ans = 0; for(int i = 0; i < m ; i++){ int l = ins[i].pos,r = ins[i].v; ans += sum[r] - sum[l - 1]; } cout<<ans<<endl; } int main(){ solved(); return 0; }
B.伤害计算
思路:模拟题。先把 ‘ + ’旁边的字符串保存起来,然后对含有 与不含有
的分别进行操作,然后计算期望
即可,注意输出的时候如果有小数点就直接.1lf,如果没有要%d,(int)ans。cout好像会出问题。(一样的代码改printf才过的).
代码:
#include<bits/stdc++.h> using namespace std; void solved(){ string s;cin>>s; vector<string>ve; string t; for(int i = 0; i < s.size(); i++){ if(s[i] == '+'){ve.push_back(t);t = "";continue;} t+=s[i]; } ve.push_back(t); double ans = 0; for(int i = 0; i < ve.size(); i++){ bool flag = false; for(int k = 0; k < ve[i].size(); k++){ if(ve[i][k] == 'd')flag = true; } if(!flag){ int t = 0; for(int k = 0; k < ve[i].size(); k++){ t = t * 10 + ve[i][k] - '0'; } ans += t; }else{ int t = 0; int pos = 0; for(int k = 0; k < ve[i].size(); k++){ if(ve[i][k] != 'd') t = t * 10 + ve[i][k] - '0'; else { pos = k + 1;break; } } int t2 = 0; for(int k = pos ; k < ve[i].size(); k++){ t2 = t2 * 10 + ve[i][k] - '0'; } ans = ans + t * (((1 + t2)*(t2 * 1.0/ 2))*1.0/t2); } } if(ans == (int)ans){ printf("%d\n",(int)ans); }else{ printf("%.1lf\n",ans); } } int main(){ solved(); return 0; }
A.张老师和菜哭武的游戏
思路:我们可以先考虑由两个数a,b对他进行+,-运算可以生成多少个数,因为张老师是先手,如果生成的所有数的个数是奇数,说明先手赢,否则输。生成的所有数满足 ,所以我们求一下
然后用总数
去除它,就是能生成的总数了。
代码:
#include<bits/stdc++.h> using namespace std; void solved(){ int t;cin>>t; while(t--){ int n,a,b;cin>>n>>a>>b; if((n/__gcd(a,b)) & 1)cout<<"Yes"<<endl; else cout<<"No"<<endl; } } int main(){ solved(); return 0; }
D.车辆调度
思路:
这个题就是暴力,我们直接枚举前k步所有车辆所有方向能走的所有情况,如果存在一个解flag=true,否则不存在解。就一个地方需要注意一下,每次一辆车的位置变了,对应的图也变了,存在数组中的当前这个R的位置也变了。(开始一直没有变数组中R的位置导致错误)。
参考了这位大哥的写法:https://ac.nowcoder.com/acm/contest/view-submission?submissionId=43705301
代码:
#include<bits/stdc++.h> using namespace std; char a[20][20]; struct node{ int x,y; node(){} node(int a,int b):x(a),y(b){} bool operator < (const node &rhs)const{ return x < rhs.x; } }; vector<node>ve; int n,m,k; int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}}; vector<node>ans; void display(){ for(int i = 1; i <= n; i++){ for(int j = 1; j <= m; j++){ cout<<a[i][j]<<" "; } cout<<endl; } cout<<endl<<endl; } bool check(int x,int y){ return x >= 1 && x <= n && y >= 1 && y <= m && a[x][y] == '.'; } bool flag = false; bool Find(int x,int y){ for(int i = 0 ; i < ans.size(); i++){ if(ans[i].x == x && ans[i].y == y)return true; } return false; } void dfs(int dep){ if(dep >= k)return ; for(int i = 0; i < ve.size(); i++){ for(int j = 0; j < 4; j++){ int x = ve[i].x;//不能动的前一步 int y = ve[i].y;//不能动的前一步 int X = ve[i].x;//原位置 int Y = ve[i].y;//原位置 int fx = x + dir[j][0],fy = y + dir[j][1]; while(check(fx,fy)){ x = fx,y = fy; fx += dir[j][0]; fy += dir[j][1]; } if(Find(x,y)){ // cout<<x<<" "<<y<<endl; // display(); flag = true; return ; } swap(a[x][y],a[X][Y]); ve[i].x = x;ve[i].y = y; dfs(dep + 1); ve[i].x = X;ve[i].y = Y; swap(a[x][y],a[X][Y]); } } } void solved(){ cin>>m>>n>>k; for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) scanf(" %c",&a[i][j]); for(int i = 1; i <= n; i++){ for(int j = 1; j <= m; j++){ if(a[i][j] == 'R')ve.push_back(node(i,j)); if(a[i][j] == 'D'){ ans.push_back(node(i,j));a[i][j] = '.'; } } } dfs(0); if(flag)cout<<"YES"<<endl; else cout<<"NO"<<endl; } int main(){ solved(); return 0; }