http://codeforces.com/contest/996
A. Hit the Lottery
解法:贪心一下就好了
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
int n;
cin>>n;
int ans=0;
ans+=n/100;
n%=100;
ans+=n/20;
n%=20;
ans+=n/10;
n%=10;
ans+=n/5;
n%=5;
ans+=n;
cout<<ans<<endl;
//system("pause");
return 0;
}
B. World Cup
题意:一个人在第一个入口,每个出口有a[i]个人在排队,每一个单位时间这个人往前走一步(如果在最后就走到第一个入口),同时,每个入口排队的人减少一个,如果走到的这个入口没人排队就可以进去,问最后这个人是从哪个入口进去的。
解法:从左往右直接计算在当前入口进去的最小时间。在当前进口进去需要的时间就是i-1+k*n
求出最小的k满足i-1+k*n>=a[i]
#include<bits/stdc++.h>
using namespace std;
#define maxn 100005
int a[maxn];
int main()
{
ios::sync_with_stdio(false);
int n,ans=0x7fffffff,pos;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++){
int temp=0;
if(a[i]>=i-1) temp=ceil(double(a[i]-i+1)/double(n));
if(temp&&i-1+(temp-1)*n>=a[i]) temp--;
temp=temp*n+i-1;
if(ans>temp){
ans=temp;
pos=i;
}
}
cout<<pos<<endl;
return 0;
}
C. Tesla
题意:第二,三行是车编号,一四行是车位编号,求出在20000步内把所有车停到对应车位的步骤。
解法:把第二三行看成一个循环,每次先检查能不能直接把车停进去,不行就把所有车顺时针旋转一次。注意必须要有空余的位置才能够把车移动过去
比较恶心的题
#include<bits/stdc++.h>
using namespace std;
#define fst first
#define snd second
const int maxn=55;
int mp[5][maxn],a[maxn*2];
int n,k;
vector<pair<int,pair<int,int>>>v;
void change(int i,int &r,int &c)
{
if(i<=n) r=2,c=i;
else r=3,c=2*n-i+1;
}
void go()
{
if(n==1){
if(mp[2][1]==0){
v.push_back({mp[3][1],{2,1}});
mp[2][1]=mp[3][1];
mp[3][1]=0;
}else if(mp[3][1]==0){
v.push_back({mp[2][1],{3,1}});
mp[3][1]=mp[2][1];
mp[2][1]=0;
}
return ;
}
for(int i=1;i<=n;i++) a[i]=mp[2][i];
for(int i=1;i<=n;i++) a[2*n-i+1]=mp[3][i];
int pos=0,r,c;
for(int i=1;i<=2*n;i++)
if(a[i]==0){
pos=i;
break;
}
for(int i=pos-1;i>=1;i--){
a[i+1]=a[i];
if(a[i]){
change(i+1,r,c);
v.push_back({a[i],{r,c}});
}
}
if(pos!=2*n){
a[1]=a[2*n];
if(a[2*n]){
change(1,r,c);
v.push_back({a[2*n],{r,c}});
}
}else{
a[1]=0;
}
for(int i=2*n;i-1>pos;i--){
a[i]=a[i-1];
if(a[i-1]){
change(i,r,c);
v.push_back({a[i-1],{r,c}});
}
}
a[pos+1]=0;
for(int i=1;i<=n;i++) mp[2][i]=a[i];
for(int i=1;i<=n;i++) mp[3][i]=a[2*n-i+1];
/*cout<<"****"<<endl;
for(int i=2;i<=3;i++){
for(int j=1;j<=n;j++){
cout<<mp[i][j]<<' ';
}
cout<<endl;
}*/
}
void check()
{
for(int i=1;i<=n;i++){
if(mp[2][i]&&mp[1][i]==mp[2][i]){
v.push_back({mp[2][i],{1,i}});
k--;
mp[2][i]=0;
}
}
for(int i=1;i<=n;i++){
if(mp[3][i]&&mp[4][i]==mp[3][i]){
v.push_back({mp[3][i],{4,i}});
k--;
mp[3][i]=0;
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin>>n>>k;
for(int i=1;i<=4;i++){
for(int j=1;j<=n;j++)
cin>>mp[i][j];
}
int cnt=0;
while(k&&cnt<=20000){
check();
if(k==0) break;
go();
cnt++;
}
if(cnt>20000){
cout<<-1<<endl;
return 0;
}
cout<<int(v.size())<<endl;
for(auto it:v)
cout<<it.fst<<' '<<it.snd.fst<<' '<<it.snd.snd<<endl;
return 0;
}
D. Suit and Tie
题意:给定一个序列(每个数都会只出现两次),每次操作可以交换两个相邻的数,求出把序列变成相等的数相邻的最小操作次数
解法:贪心一下,从左往右,依次把与当前相等的数移过来就好
#include<bits/stdc++.h>
using namespace std;
#define maxn 100005
int a[maxn];
int main()
{
ios::sync_with_stdio(false);
int n;
cin>>n;
for(int i=1;i<=2*n;i++) cin>>a[i];
int ans=0;
for(int i=1;i<=2*n;i+=2){
for(int j=i+1;j<=2*n;j++){
if(a[j]==a[i]){
ans+=j-i-1;
for(int k=j;k>i;k--) swap(a[k],a[k-1]);
}
}
}
cout<<ans<<endl;
return 0;
}
E. Leaving the Bar
题意:有n个向量,可以对向量进行反向,求出把所有向量加起来后的模长<1.5e6 的方案(-1表示对向量进行反向)
解法:先遍历所有的向量,如果加上该向量后总模长比减去该向量模长短,则这个向量不用反向,否则就反向;然后再对答案进行一次修正
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define x first
#define y second
const int maxn = 1e5 + 5;
pair<pair<int, int>, int>p[maxn];
int n;
int c[maxn];
LL maxx = 1.5 * 1e6;
int main()
{
ios::sync_with_stdio(false);
cin >> n;
for(int i = 1; i <= n; i++) {
cin >> p[i].x.x >> p[i].x.y;
p[i].y = i;
}
int sumx = 0, sumy = 0;
for(int i = 1; i <= n; i++) {
LL t1 = 1LL * (sumx + p[i].x.x) * (sumx + p[i].x.x) + 1LL * (sumy + p[i].x.y) * (sumy + p[i].x.y);
LL t2 = 1LL * (sumx - p[i].x.x) * (sumx - p[i].x.x) + 1LL * (sumy - p[i].x.y) * (sumy - p[i].x.y);
if(t1 <= t2) {
c[p[i].y] = 1;
sumx += p[i].x.x;
sumy += p[i].x.y;
} else {
c[p[i].y] = -1;
sumx -= p[i].x.x;
sumy -= p[i].x.y;
}
}
for(int i = 1; i <= n; i++) {
LL temp = 1LL * sumx * sumx + 1LL * sumy * sumy;
if(temp <= maxx) {
break;
}
LL t1, t2;
if(c[i] == 1) {
t1 = sumx - 2 * p[i].x.x;
t2 = sumy - 2 * p[i].x.y;
if(t1 * t1 + t2 * t2 < temp) {
sumx = t1;
sumy = t2;
c[i] = -1;
}
} else {
t1 = sumx + 2 * p[i].x.x;
t2 = sumy + 2 * p[i].x.y;
if(t1 * t1 + t2 * t2 < temp) {
sumx = t1;
sumy = t2;
c[i] = 1;
}
}
}
for(int i = 1; i <= n; i++) {
cout << c[i] << ' ';
}
return 0;
}
F. Game
题意都没有读懂