A
好傻的,我还用了二分
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define mst(a, b) memset(a, b, sizeof a)
#define REP(i, x, n) for(int i = x; i <= n; ++i)
const int qq = 2e5 + 10;
LL n, k;
bool Check(LL x){
if(x == 0) return true;
if((n / 2 - x) / x >= k) return true;
return false;
}
int main(){
cin >> n >> k;
LL l = 0, r = n / 2, mid;
LL ans = 0;
while(l <= r){
mid = (l + r) / 2;
if(Check(mid)){
ans = mid;
l = mid + 1;
}else{
r = mid - 1;
}
}
printf("%lld %lld %lld\n", ans, ans * k, n - (ans + ans * k));
return 0;
}
B
题意:n个数(1~n)组成的序列,m次操作,每次操作数i,然后到数字为i + ai的地方,如此操作下去,求符合要求的数组a
思路:直接枚举第一个数再数组a中的位置,然后check即可
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define mst(a, b) memset(a, b, sizeof a)
#define REP(i, x, n) for(int i = x; i <= n; ++i)
const int qq = 2e5 + 10;
int n, m;
int num[105];
int loca[105];
int vis[105];
map<int, bool> mp;
int x[105];
bool Check(){
mst(vis, 0);
for(int i = 1; i <= n; ++i){
if(!num[i]) continue;
if(!vis[num[i]]) vis[num[i]] = 1;
else return false;
}
return true;
}
int main(){
cin >> n >> m;
REP(i, 1, m){
scanf("%d", loca + i);
}
bool f = false;
for(int i = 1; i <= n; ++i){
mst(num, 0);
num[i] = loca[1];
bool t = true;
for(int j = 2; j <= m; ++j){
int a = loca[j - 1], b = loca[j];
int cnt = 0;
while(1){
++a, ++cnt;
if(a > n) a = 1;
if(a == b) break;
}
if(!num[loca[j - 1]]){
num[loca[j - 1]] = cnt;
}else{
if(num[loca[j - 1]] != cnt){
t = false;
break;
}
}
}
/* for(int j = 1; j <= n; ++j)
printf("%d ", num[j]);
puts("");*/
if(!t) continue;
if(!Check()) continue;
if(t){
f = true;
break;
}
}
if(!f){
puts("-1");
return 0;
}
for(int i = 1; i <= n; ++i){
mp[num[i]] = true;
}
int cnt = 0;
for(int i = 1; i <= n; ++i){
if(!mp[i]) x[cnt++] = i;
}
cnt = 0;
for(int i = 1; i <= n; ++i){
if(!num[i]) num[i] = x[cnt++];
}
for(int i = 1; i <= n; ++i)
printf("%d ", num[i]);
puts("");
return 0;
}
C
题意:由d个沙发,分布在n × m的矩阵内,然后给出numl, numr, numt, numb分别代表某个沙发左边,右边,上边,下边的沙发数量,让你求出这个沙发的index,一个沙发占两个有公共边的格子。
思路:分四个方向分别统计前缀和后缀,然后枚举每一个沙发,看是否满足所给定的沙发数量
#include <cstdio>
#include <cstring>
#include <map>
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define pill pair<int, int>
#define mst(a, b) memset(a, b, sizeof a)
#define REP(i, x, n) for(int i = x; i <= n; ++i)
const int qq = 2e5 + 10;
int dirc[qq][4];
int point[qq][4];
int main(){
int d, n, m;
scanf("%d%d%d", &d, &n, &m);
REP(i, 1, d){
scanf("%d%d%d%d", &point[i][0], &point[i][2], &point[i][1], &point[i][3]);
if(point[i][0] > point[i][1]) swap(point[i][0], point[i][1]);
if(point[i][2] > point[i][3]) swap(point[i][2], point[i][3]);
REP(j, 0, 3){
dirc[point[i][j]][j]++;
}
}
int cntl, cntr, cntt, cntb;
scanf("%d%d%d%d", &cntl, &cntr, &cntt, &cntb);
for(int i = 1; i <= n; ++i)
dirc[i][0] += dirc[i - 1][0];
for(int i = n; i >= 1; --i)
dirc[i][1] += dirc[i + 1][1];
for(int i = 1; i <= m; ++i)
dirc[i][2] += dirc[i - 1][2];
for(int i = m; i >= 1; --i)
dirc[i][3] += dirc[i + 1][3];
for(int i = 1; i <= d; ++i){
int l = point[i][0], r = point[i][1], b = point[i][2], t = point[i][3];
int numl = dirc[r - 1][0], numr = dirc[l + 1][1], numt = dirc[t - 1][2], numb = dirc[b + 1][3];
if(l == r){
numt--, numb--;
}else{
numl--, numr--;
}
if(numl == cntl && numr == cntr && numt == cntt && numb == cntb){
printf("%d\n", i);
return 0;
}
}
puts("-1");
return 0;
}
D
题意:给定n个数,然后一个数字B,问是否存在一个数A,对于数字A的前缀和在任意一个i都满足cntA(i) >= cntB(i),求出这个数。
思路:恩~~~感觉想到了就是很简单的,看代码吧。
我感觉实际上可以这样想,就是对于每一个数字B与数字B之间都要存在某个数,注意第一个B前面也要存在。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define mst(a, b) memset(a, b, sizeof a)
#define REP(i, x, n) for(int i = x; i <= n; ++i)
const int qq = 1e6 + 10;
int num[qq];
int n, A;
map<int, int> mp;
int main(){
scanf("%d%d", &n, &A);
for(int i = 1; i <= n; ++i){
int x; scanf("%d", &x);
if(x == A) num[A]++;
else if(num[x] >= num[A]) num[x]++;
}
for(int i = 1; i <= 1e6; ++i)
if(i != A && num[i] >= num[A]){
printf("%d\n", i);
return 0;
}
puts("-1");
return 0;
}