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