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;
}
京公网安备 11010502036488号