#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
/*【A. Hit the Lottery】
有n元钱(!),面值为1,5,10,20,100,求最少的纸币数目。 */
int main(){
int n,ans=0; scanf("%d",&n);
ans+=n%5; n-=n%5;
ans+=(n%10)/5; n-=n%10;
ans+=(n%20)/10; n-=n%20;
ans+=(n%100)/20; n-=n%100;
ans+=n/100;
printf("%d\n",ans);
return 0;
}
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
/*【B. World Cup】
有n个入口。在第i个入口前面有ai人。
每个入口允许其队列中的一个人在一分钟内进入。
Allen使用以下策略进入:1.最初,他站在第一个入口前排队的尽头。
2.每一分钟,如果他在一分钟内不被允许进入(意味着他不是队列中的第一个),
他离开当前队列并站在下一个入口(离开了最后一个入口后进入第一个入口)。
确定艾伦最终进入的入口。 */
int a[100009];
int main(){
int n; cin>>n; int min_=1e9+10;
for(int i=0;i<n;i++) cin>>a[i],min_=min(min_,a[i]);
int lazy=min_; //lazy标记
int t=min_; t%=n;
while(1){
if(a[t]-lazy<=0){ cout<<t+1<<endl; return 0;}
else lazy++;
t++; t%=n;
}
return 0;
}
【C.Tesla】
4*n停车场,第二行和第三行是过道,第一行和第四行是车库,0表示空地。
在过道的车可以上下左右四个方向随意走动,车一旦进入第一和第四行就不能动了。
现在有k辆车(1~k)要停车,编号为 i 的车要停入编号为 i 的车库,保证车和车库的编号都只有一个。
一辆车移动一下算一步,现在要把所有的车入库,请你输出一种20000步以内的解法,没有输出-1。
思路 //来自 https://blog.csdn.net/ZscDst/article/details/80821376
我们让这些车在第二行和第三行兜圈子走,如果哪个车可以停入对应的车库就让他停进去,其他的继续。
如果初始状态下,所有车都停不进去且没有空位,那么就无解。
一旦有一个空位可以用于挪动车辆,我们照此方法就可以把所有车停进去。
最坏情况下每个车都移动了一圈才停进去,移动次数为100*100+100,所以方案可行。
接下来就是个大模拟了…
把第二行和第三行对接到了一起(按照图中转圈方向),第一行和第四行按照同样的方法对接到一起。
比如第一个样例:
4 5
1 2 0 4
1 2 0 4
5 0 0 3
0 5 0 3
变为:
2 10
1 2 0 4 3 0 5 0
1 2 0 4 3 0 0 5
这样的话第一行就是车库,第二行就是车所在的过道。
对于第一行第i个位置,如果 i/n=0 证明在第一列的 i%n+1 位置,否则就是在第四列的倒数 i%n+1 位置。
对于第二行第i个位置,如果 i/n=0 证明在第二列的 i%n+1 位置,否则就是在第三列的倒数 i%n+1 位置。
我们把第二行和第三行中的车和空地理解成一列火车在旋转,车头为一个空地,每次后面的车厢都往前走了一节。
在变换后的数组中其实就是每个数字都往后面移动了一位,最后一位变为第一位。
但是,顺序是红色箭头,黑色的箭头,绿色箭头。一直旋转停车,直到所有车都入库,
过程中如果是车的移动就用ans记录下路径。
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 205;
int n, k, a[5][MAXN], s;//s是火车头
struct Node
{
int id, x, y;
Node(int id, int x, int y): id(id), x(x), y(y) {}
};
vector<Node> ans;
void park()//尝试停车
{
for (int i = 0; i < 2*n; i++) if (a[1][i] && a[1][i] == a[0][i])
{//入库,记录路径
ans.push_back(Node(a[1][i], i/n?4:1, i%n+1));
a[1][i] = 0; k--;
}
}
bool judge()//有解?
{
park();
for (int i = 0; i < 2*n; i++) if (!a[1][i]) return true;
return false;
}
void turn()
{
vector<Node> v1, v2;
int t = a[1][2*n-1];
for (int i = 2*n-1; i >= 1; i--)
{
a[1][i] = a[1][i-1];
if (a[1][i])//是车的移动,记录路径
{
if (i > s) v1.push_back(Node(a[1][i], i/n?3:2, i%n+1));//绿色箭头
else v2.push_back(Node(a[1][i], i/n?3:2, i%n+1));//红黑箭头
}
}
a[1][0] = t; if (t) v2.push_back(Node(t, 2, 1));
for (auto i: v2) ans.push_back(i);//红黑箭头
for (auto i: v1) ans.push_back(i);//绿色箭头
}
int main()
{
scanf("%d%d", &n, &k);
for (int i = 0; i < n; i++) scanf("%d", &a[0][i]);
for (int i = 0; i < n; i++) scanf("%d", &a[1][i]);
for (int i = 2*n-1; i >= n; i--) scanf("%d", &a[1][i]);
for (int i = 2*n-1; i >= n; i--) scanf("%d", &a[0][i]);
if (!judge()) { printf("-1\n"); return 0; } //判断无解
for (int i = 0; i < 2*n; i++) if(!a[1][i]) { s = i; break; } //找火车头
while (k)
{
turn(); park();//旋转,尝试停车
s = (s+1)%(2*n);
}
printf("%d\n", ans.size());
for (auto i: ans)
{
if (i.x == 3 || i.x == 4) i.y = n-i.y+1;//倒数变正数
printf("%d %d %d\n", i.id, i.x, i.y);
}
return 0;
}
/*
4 5
1 2 0 4
1 2 0 4
5 0 0 3
0 5 0 3
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
/*【D. Suit and Tie】
给你2*n个数,把相同的数放在一起最小需要移动多少次位置。 */
//贪心,每次找和自己相同的数的位置,中间已访问的数记为-1,不再访问。
//加{ 每次找到的位置减去数自己的位置减去一 }, 再减{ 中间已经被找到的数 }。
int a[209],okk[209];
int main(){
int n,ans=0; scanf("%d",&n);
for(int i=1;i<=2*n;i++) scanf("%d",&a[i]);
for(int i=1;i<2*n;i++)
if(okk[i]!=-1)
for(int j=i+1;j<=2*n;j++){
if(okk[j]==-1) ans-=1; //已经配对的
if(a[i]==a[j]){
okk[i]=-1; okk[j]=-1;
ans+=j-i-1;
break;
}
}
cout<<ans<<endl;
return 0;
}
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
/*【E. Leaving the Bar】
给定一些向量,你可以改变它的符号,使得这些向量之和的长度小于1.5e6。
【分析】可以将速度分解成为x,y轴方向上的分量,每次贪心取最小,
因为每次我贪心原则是一样的,最后的结果有可能大于1.5e6 ,我们需要加一些随机性,
多次贪心,直到结果满足题意。正解是每三个向量中都能找到两个向量合起来 <= 1e6,
然后不断合并,最后只会剩下一个或者两个向量,如果一个向量肯定 <= 1e6,
如果是两个向量一定 <= 1.5 * 1e6。 */
const int maxn = 1e5 + 100;
struct node {
int id;
ll x, y;
} data[maxn];
int ans[maxn];
int main() {
srand(time(NULL));
int n; scanf("%d", &n);
for(int i = 1; i <= n; i++) {
cin>>data[i].x>>data[i].y;
data[i].id = i;
}
while(true) {
ll tmp = 0, t1, t2;
ll prex = data[1].x, prey = data[1].y;
ans[data[1].id] = 1;
for(int i = 2; i <= n; i++) {
ll tx1 = prex - data[i].x;
ll ty1 = prey - data[i].y;
t1 = tx1 * tx1 + ty1 * ty1;
ll tx2 = data[i].x + prex;
ll ty2 = data[i].y + prey;
t2 = tx2 * tx2 + ty2 * ty2;
if(t1 < t2) {
ans[data[i].id] = -1;
prex = tx1; prey = ty1;
}
else {
ans[data[i].id] = 1;
prex = tx2;
prey = ty2;
}
}
if(min(t1, t2) <= 2250000000000LL)
break;
else random_shuffle(data + 1, data + n + 1);
}
for(int i = 1; i <= n; i++)
printf("%d%c", ans[i], i == n ? '\n' : ' ');
return 0;
}
——时间划过风的轨迹,那个少年,还在等你。
4*n停车场,第二行和第三行是过道,第一行和第四行是车库,0表示空地。
在过道的车可以上下左右四个方向随意走动,车一旦进入第一和第四行就不能动了。
现在有k辆车(1~k)要停车,编号为 i 的车要停入编号为 i 的车库,保证车和车库的编号都只有一个。
一辆车移动一下算一步,现在要把所有的车入库,请你输出一种20000步以内的解法,没有输出-1。
思路 //来自 https://blog.csdn.net/ZscDst/article/details/80821376
我们让这些车在第二行和第三行兜圈子走,如果哪个车可以停入对应的车库就让他停进去,其他的继续。
如果初始状态下,所有车都停不进去且没有空位,那么就无解。
一旦有一个空位可以用于挪动车辆,我们照此方法就可以把所有车停进去。
最坏情况下每个车都移动了一圈才停进去,移动次数为100*100+100,所以方案可行。
接下来就是个大模拟了…
把第二行和第三行对接到了一起(按照图中转圈方向),第一行和第四行按照同样的方法对接到一起。
比如第一个样例:
4 5
1 2 0 4
1 2 0 4
5 0 0 3
0 5 0 3
变为:
2 10
1 2 0 4 3 0 5 0
1 2 0 4 3 0 0 5
这样的话第一行就是车库,第二行就是车所在的过道。
对于第一行第i个位置,如果 i/n=0 证明在第一列的 i%n+1 位置,否则就是在第四列的倒数 i%n+1 位置。
对于第二行第i个位置,如果 i/n=0 证明在第二列的 i%n+1 位置,否则就是在第三列的倒数 i%n+1 位置。
我们把第二行和第三行中的车和空地理解成一列火车在旋转,车头为一个空地,每次后面的车厢都往前走了一节。
在变换后的数组中其实就是每个数字都往后面移动了一位,最后一位变为第一位。
但是,顺序是红色箭头,黑色的箭头,绿色箭头。一直旋转停车,直到所有车都入库,
过程中如果是车的移动就用ans记录下路径。