文章目录
- A. Remove Duplicates
- B. File Name
- C. Letters
- D. Almost Arithmetic Progression
- E. Bus Video System
- F. Mentors
- G. Petya's Exams
A. Remove Duplicates
- 题意
给你一个有个整数的数组,现在需要删掉重复的元素,仅保留每个元素最右边的那个,且元素的相对顺序不应改变。
- 解题思路
利用记录每个值最后出现得位置,再桶排序输出即可。
- AC代码
/**
*@filename:B
*@author: pursuit
*@created: 2021-08-11 18:59
**/
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N = 1e5 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int t,n;
int a[N];
int cnt = 0;
map<int,int> p;
void solve(){
memset(a,0,sizeof(a));
for(auto &x : p){
a[x.second] = x.first;
}
cout << cnt << endl;
for(int i = 1; i <= n; ++ i){
if(a[i]){
cout << a[i] << " ";
}
}
cout << endl;
}
int main(){
cin >> n;
for(int i = 1; i <= n; ++ i){
cin >> a[i];
if(!p[a[i]]){
cnt ++;
}
p[a[i]] = i;
}
solve();
return 0;
}
B. File Name
- 题意
给出一串字符串,判断里面有多少对xxx
- 解题思路
顺序遍历统计即可。 - AC代码
/*
*注:文章若有任何问题请私信我或评论区留言,谢谢支持。
*
*/
//POJ不支持
//i为循环变量,a为初始值,n为界限值,递增
//i为循环变量, a为初始值,n为界限值,递减。
using namespace std;
const int inf = 0x3f3f3f3f;//无穷大
const int maxn = 1e5;//最大值。
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
//*******************************分割线,以上为自定义代码模板***************************************//
int n;
string s;
int main(){
//freopen("in.txt", "r", stdin);//提交的时候要注释掉
IOS;
while(cin>>n){
cin>>s;
ll ans=0;
ll sum=0;
rep(i,0,n-1){
if(s[i]=='x'){
sum++;
}
else{
if(sum>=3){
ans+=(sum-2);
}
sum=0;
}
}
if(sum>=3){
ans+=(sum-2);
}
cout<<ans<<endl;
}
return 0;
}
C. Letters
- 题意
有栋公寓,其中每个公寓有
得房间,给出
个信封所需送往的房间编号。判断所属门牌号。
- 解题思路
利用前缀和统计前个公寓的房间数,然后二分查找属于第几个公寓即可。
- AC代码
/**
*@filename:C
*@author: pursuit
*@created: 2021-08-11 19:04
**/
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N = 2e5 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int n,m;
ll a[N],b[N],sum[N];
void solve(){
for(int i = 1; i <= m; ++ i){
int idx = lower_bound(sum + 1,sum + 1 + n,b[i]) - sum;
printf("%d %lld\n", idx,b[i] - sum[idx - 1]);
}
}
int main(){
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++ i){
scanf("%lld", &a[i]);
sum[i] = sum[i - 1] + a[i];
}
for(int i = 1; i <= m; ++ i){
scanf("%lld", &b[i]);
}
solve();
return 0;
}
D. Almost Arithmetic Progression
- 题意
给定一个整数序列,需要将这个序列变成等差数列。其中数列中的每个元素,都可以至多选择一种操作:保持不变。请输出最小操作次数。
- 解题思路
我们注意到,公差一定在相邻两数差值的最小值和最大值之内。而由于其操作限定性,所以才有可能存在,其余的都不可能,处理好这个我们就可以枚举公差了,同时由于首项只有两种情况,我们也确定好首项然后验证合法性解决即可。注意特判
的情况。
- AC代码
/**
*@filename:D
*@author: pursuit
*@created: 2021-08-11 19:14
**/
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N = 1e5 + 10;
const int P = 1e9 + 7;
const ll INF = 1e10;
int n;
ll b[N],minn = INF,maxx = -INF,c[N];
void solve(){
bool flag = false;
if(n <= 2){
puts("0");
return;
}
if(maxx - minn > 4){
puts("-1");
}
else{
ll ans = INF;
for(int d = minn; d <= maxx; ++ d){
for(int j = 0; j < 3; ++ j){
for(int i = 1; i <= n; ++ i){
c[i] = b[i];
}
ll cnt = 0;
bool flag = true;
if(j == 1){
c[1] += 1;
cnt ++;
}
else if(j == 2){
c[1] -= 1;
cnt ++;
}
//cout << c[1] << " ";
for(int i = 2; i <= n; ++ i){
if(abs(c[i] - c[i - 1] - d) > 1){
flag = false;
break;
}
else if(abs(c[i] - c[i - 1] - d) == 1){
cnt ++;
c[i] = c[i - 1] + d;
}
//cout << c[i] << " ";
}
//cout << endl;
if(flag){
ans = min(ans,cnt);
}
}
}
if(ans == INF){
puts("-1");
}
else{
printf("%lld\n", ans);
}
}
}
int main(){
scanf("%d", &n);
for(int i = 1; i <= n; ++ i){
scanf("%lld", &b[i]);
if(i >= 2){
minn = min(minn,b[i] - b[i - 1]);
maxx = max(maxx,b[i] - b[i - 1]);
}
}
solve();
return 0;
}
E. Bus Video System
- 题意
公交车最多容纳w人,初始车上人数未知,经过n个站,每个站上车和下车人数给出,问车上一开始的人数有多少种可能,若方案不存在输出0。 - 解题思路
初始我们设置最小人数为,最多人数为
,然后每次统计现有公交车人数,根据其合理性调整这两个数值。最后即是
。
- AC代码
/**
*@filename:E
*@author: pursuit
*@created: 2021-08-11 19:29
**/
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N = 1e3 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int n,w,a[N];
void solve(){
int maxx = w,minn = 0;
bool flag = false;
int cur = 0;
for(int i = 1; i <= n; ++ i){
cur += a[i];
if(cur + minn < 0){
minn = 0 - cur;
}
else if(cur + maxx > w){
maxx = w - cur;
}
}
if(maxx < minn){
puts("0");
}
else{
printf("%d", maxx - minn + 1);
}
}
int main(){
scanf("%d%d", &n, &w);
for(int i = 1; i <= n; ++ i){
scanf("%d", &a[i]);
}
solve();
return 0;
}
F. Mentors
- 题意
在BerSoft n个程序员的工作中,程序员i的特点是技能ri。 当且仅当程序员a的技能严格大于程序员b的技能(ra> rb)且程序员a和b不吵架时,程序员a才可以是程序员b的指导者。系统会为您提供每个程序员的技能以及k对程序员的清单,它们在争吵中(对是无序的)。对于每个程序员i,找到程序员i可以担任其导师的程序员数量。 - 解题思路
存储好对应的技能和争吵关系,对于每个人二分查找得到多少个小于他的,同时再二分找出多少个小于他的且有争吵关系的,两者之差则是答案。 - AC代码
/**
*@filename:F
*@author: pursuit
*@created: 2021-08-11 19:40
**/
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N = 2e5 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int n,m,r[N],pos[N],ans[N];
vector<int> g[N];
bool cmp(int i,int j){
return r[i] < r[j];
}
void solve(){
sort(pos + 1,pos + 1 + n,cmp);
for(int i = 1; i <= n; ++ i){
sort(g[i].begin(),g[i].end(),cmp);
}
for(int i = 1; i <= n; ++ i){
int u = pos[i],w = r[pos[i]];//寻找
int L = 1,R = n;
while(L < R){
int mid = (L + R) >> 1;
if(r[pos[mid]] < w){
L = mid + 1;
}
else{
R = mid;
}
}
ans[u] = L - 1;
if(g[u].size() != 0){
//debug(u);
int L = 0, R = g[u].size();
while(L < R){
int mid = (L + R) >> 1;
if(mid == g[u].size()){
L = mid;
break;
}
int v = g[u][mid];
//debug(v);
if(r[v] < w){
L = mid + 1;
}
else{
R = mid;
}
}
//cout << L << endl;
ans[u] -= L;
}
}
for(int i = 1; i <= n; ++ i){
printf("%d ", ans[i]);
}
puts("");
}
int main(){
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++ i){
scanf("%d", &r[i]);
pos[i] = i;
}
int u,v;
for(int i = 1; i <= m; ++ i){
scanf("%d%d", &u, &v);
g[u].push_back(v);
g[v].push_back(u);
}
solve();
return 0;
}
G. Petya’s Exams
- 题意
给你一些考试信息,有天可以用,问你可以合理安排的方案,若不存在,则输出
。
- 解题思路
贪心即可,按考试时间从小到达排序,然后从开始准备日期开始准备。需要注意的一点就是不能占用其他考试日期。 - AC代码
/**
*@filename:G
*@author: pursuit
*@created: 2021-08-11 20:53
**/
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N = 1e5 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int n,m;
struct node{
int id,s,d,c;//s为开始准备考试日期。d为考试日期,c为需要准备的考试天数。
bool operator < (const node & A){
return d < A.d;
}
}item[N];
int ans[N];
bool vis[N];//考试不能占用。
void solve(){
int cnt = 0;
sort(item + 1,item + 1 + m);
bool flag = true;
for(int i = 1; i <= m; ++ i){
int cnt = 0;
for(int j = item[i].s; j < item[i].d && cnt < item[i].c; ++ j){
if(!ans[j] && !vis[j]){
ans[j] = item[i].id;
cnt ++;
}
}
if(cnt < item[i].c || ans[item[i].d]){
flag = false;
break;
}
else{
ans[item[i].d] = m + 1;
}
}
if(!flag){
puts("-1");
}
else{
for(int i = 1; i <= n; ++ i){
printf("%d ", ans[i]);
}
puts("");
}
}
int main(){
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; ++ i){
scanf("%d%d%d", &item[i].s, &item[i].d, &item[i].c);
vis[item[i].d] = true;
item[i].id = i;
}
solve();
return 0;
}