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;
}