A:有5,20,,,,的金币,然后怎么怎么样,略
B:有n个数,每次走一步,每个数都会减少1,当减少到0的时候就不会改变了,问你最少多少步可以走到是0的数上
ll a[maxn];
int main() {
ios::sync_with_stdio(false);
while(cin >> n){
for(int i = 1;i <= n;i++){
cin >> a[i];
}
ll ans = 0;
while(1){
for(int i = 1;i <= n;i++){
if(a[i] < i){
cout << i << endl;
return 0;
}
}
int Min = 1e9;
for(int i = 1;i <= n;i++) Min = min(Min,a[i] / n);
if(Min == 0){
while(1){
for(int i = 1;i <= n;i++){
a[i] -= i;
if(a[i] < 0){
cout << i << endl;
return 0;
}
a[i] -= (n - i);
}
}
}
for(int i = 1;i <= n;i++){
a[i] = max(0,a[i] - Min * n);
}
}
}
}
代码写的有点丑了,反正就是模拟加模拟,先除一边,然后挨个减,当除数为0的时候,去减一下就可以了(因为跑不过两轮就会结束)
C:(模拟),有n * 2 个停车位,以及一些车车,每个车都有一个编号,它必须·停在编号相同的停车场里,在不超过20000
可以把第四行和第三行折到第一行和第二行上,这样在处理的时候 就方便多了,然后对于每次只要移动第二行的上的车车就可以了,具体模拟的时候下标怎么变动 , 大家自己模拟一下就知道了。
代码:
ll n,k,m;
int a[5][maxn];
struct node{
int id,x,y;
};
vector<node>ans;
P getxy(int id,int x) {
P p;
if(id == 2){
if(x > n){
x -= n;
p.fi = 3,p.se = (n - x + 1);
}else p.fi = id,p.se = x;
}else{
if(x > n){
x -= n; p.fi = 4,p.se = (n - x + 1);
}else p.fi = id,p.se = x;
}
return p;
}
void getans(P p,int k)
{
ans.push_back(node{k,p.fi,p.se});
return ;
}
bool vis[maxn];
bool check(int i){
if(a[1][i] == a[2][i] && a[2][i] != 0&&!vis[i]){
int x = 1, y = i;
vis[i] = 1;
P p = getxy(1,i);
getans(p,a[2][i]);
a[2][i] = 0;
k--;
}
}
void movee(){
int id = 1;
for(int i = 1;i <= 2 * n;i++){
if(a[2][i] == 0){
id = i;break;
}
}
for(int i = id;i >= 1;i--){
if(a[2][i - 1]){
if(i == 1){
P p = getxy(2,2 * n);
getans(p,a[2][i - 1]);
swap(a[2][2 * n],a[2][i ]);
}else{
P p = getxy(2,i);
getans(p,a[2][i - 1]);
swap(a[2][i- 1],a[2][i ]);
}
}
}
for(int i = n * 2;i >= id + 1;i--){
if(a[2][i]){
if(i == 2 * n){
P p = getxy(2,1);
getans(p,a[2][i]);
swap(a[2][2 * n],a[2][1]);
}else {
P p = getxy(2,i + 1);
getans(p,a[2][i]);
swap(a[2][i +1],a[2][i]);
}
}
}
return ;
}
int main() {
n = read();k = read();
for(int j = 1;j <= 4;j++) for(int i = 1;i <= n;i++) a[j][i] = read();
ll x = k;
for(int j = 1;j <= n;j++) a[1][n + j] = a[4][n + 1 - j];
for(int j = 1;j <= n;j++) a[2][n + j] = a[3][n + 1 - j];
for(int i = 1;i <= 2 * n;i++) check(i);
int flag = 0;
for(int i = 1;i <= n * 2;i++) if(a[2][i] == 0) flag = 1;
if(!flag) return cout << -1 <<endl,0;
while(k){
for(int i = 1;i <= n * 2;i++)
check(i) ;
movee();
}
cout << ans.size() << endl;
for(auto d:ans) cout << d.id << " " <<d.x << " " << d.y << endl;
return 0;
}
//
D:让你用最小的移动次数,把n * 2 个数,相同的数变成相邻的。
前面的数不动,直接模拟就可以了。
ll n,k;
ll a[maxn];
vector<int>v[maxn];
int main() {
ios::sync_with_stdio(false);
while(cin >> n){
for(int i = 1;i <= n * 2;i++) cin >> a[i],v[a[i]].push_back(i);
int ans = 0;
int l = 1,r = 1;
for(int i = 1;i <= n * 2;i += 2){
if(a[i] != a[i + 1]){
int id = 0;
for(int j = i + 1; j <= n * 2;j++){
if(a[i] == a[j]){
id = j;
break;
}
}
for(int j = id;j > i + 1;j--){
ans ++;swap(a[j],a[j - 1]);
}
}
}
cout << ans << endl;
}
return 0;
}
E:有n个向量,你可以取正或者负,最后走完这些向量,要求距离原点不超过1.5e6
随机化 + 枚举,找出来一种符合的方式(具体原理我也搞不懂,自己随机贪心一直T39)
ll n,k,m;
ll a[maxn];
struct node{
ll a,b,id,ans;
}p[maxn];
bool cmp(node a,node b){
return abs(a.a - a.b) < abs(b.a - b.b);
}
bool cmp1(node a,node b){
return a.id < b.id ;
}
int main() {
ios::sync_with_stdio(false);
while(cin >> n){
for(int i = 1;i <= n;i++) cin >> p[i].a >>p[i].b,p[i].id = i;
while(1){
random_shuffle(p + 1,p + 1 + n);
// sort(p + 1,p + 1 + n,cmp);
ll x = 0,y = 0; ll dis = 0;
for(int i = n;i >= 1;i--){
dis = (x + p[i].a) * (x + p[i].a) + (y + p[i].b) * (y + p[i].b);
if(dis <= (x - p[i].a) * (x - p[i].a) + (y - p[i].b) * (y - p[i].b) ){
x += p[i].a;
y += p[i].b;
dis = x * x + y * y;
p[i].ans = 1;
}else{
x -= p[i].a;
y -= p[i].b;
dis = x * x + y * y;
p[i].ans = -1;
}
}
// cout << dis << endl;
if(sqrt(dis) <= 1.5e6){
break;
}
}
sort(p + 1,p + 1 + n,cmp1);
for(int i = 1;i <= n;i++){
cout << p[i].ans << " ";
}
}
}