这波 div2
上大分,写波题解。
实况录屏在这
A. Game with Cards 题目描述
题目分析 题目的意思就是说,Alice
和 Bob
分别有 n,m
张牌,然后每次出牌不能小于等于上一次的出牌,如果到自己的回合却不能出牌则判负,问如果两人分别先手,谁会赢?这个稍微想一下就能发现我一开始出最大的一定是最优的策略,比的就是最大值谁最大,假设相等那我肯定出最大的那个我必赢,所以无脑比最大就是这题的思路,如果相等那么谁先手谁赢,所以这里就分三种情况:
max1>max2
:Alice
必赢
max1<max2
:Bob
必赢
max1==max2
:谁先手谁赢
标程 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 #include <bits/stdc++.h> #define maxn 200005 using namespace std;int a[maxn];char s[maxn];void solve () { int n,x; cin>>n; int max1=0 ,max2=0 ; for (int i=1 ;i<=n;i++){ scanf ("%d" ,&x); max1=max (max1,x); } cin>>n; for (int i=1 ;i<=n;i++){ scanf ("%d" ,&x); max2=max (max2,x); } if (max1>max2){ puts ("Alice\nAlice" ); } else if (max1<max2){ puts ("Bob\nBob" ); } else { puts ("Alice\nBob" ); } } int main () { #ifndef ONLINE_JUDGE freopen ("1.in" ,"r" ,stdin); #endif int t=1 ; cin>>t; while (t--)solve (); return 0 ; }
B. Card Trick 题目描述
题目分析 一个以前经常玩的魔术,就是假装洗牌,实则那张牌在哪里记得清清楚楚。给一个序列,每次操作会把前 k
个值移动到最后去。问经过若干次操作之后第一个牌的值是多少,不难发现如果进行一次操作相当于第 k+1
张牌会变成第一张牌,因为是直接移动,不改变顺序,所以不难想到改题目就是统计所有的操作次数最后对 n
取模得到的下标就是第一张牌的位置。
标程 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <bits/stdc++.h> #define maxn 200005 using namespace std;int a[maxn];char s[maxn];void solve () { int n,x,op,ans=0 ; cin>>n; for (int i=1 ;i<=n;i++){ scanf ("%d\n" ,&a[i]); } cin>>x; for (int i=1 ;i<=x;i++){ scanf ("%d" ,&op); ans+=op; ans%=n; } printf ("%d\n" ,a[ans+1 ]); } int main () { #ifndef ONLINE_JUDGE freopen ("1.in" ,"r" ,stdin); #endif int t=1 ; cin>>t; while (t--)solve (); return 0 ; }
C. Double Sort 题目描述
题目分析 给两个序列,每次一起交换,问最后能否交换成都不递减,且若能则输出交换次数最少的方案。我们直接定义结构体存储两个序列的值再重载小于号,让它严格按 a
递增,相等的情况按 b
递增,因为交换次数最少,不难想到用选择排序可以达到交换次数最少的目的。那么我们就先排个序,然后判断 b
的值是否不递减就可以了。
标程 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 #include <bits/stdc++.h> #define maxn 200005 using namespace std;char s[maxn];struct A { int a,b; void in () { } bool operator <(const A &q){ if (a==q.a){ return b<q.b; } return a<q.a; } }a[maxn]; queue<pair<int ,int >>ans; void solve () { int n; cin>>n; queue<pair<int ,int >>().swap (ans); for (int i=1 ;i<=n;i++){ scanf ("%d" ,&a[i].a); } for (int i=1 ;i<=n;i++){ scanf ("%d" ,&a[i].b); } for (int i=1 ;i<n;i++){ int idx=i; for (int j=i+1 ;j<=n;j++){ if (a[j]<a[idx]){ idx=j; } } if (idx!=i){ ans.push ({idx,i}); swap (a[i],a[idx]); } } for (int i=2 ;i<=n;i++){ if (a[i-1 ].b>a[i].b){ puts ("-1" ); return ; } } printf ("%d\n" ,ans.size ()); while (ans.size ()){ auto x=ans.front (); ans.pop (); printf ("%d %d\n" ,x.first,x.second); } } int main () { #ifndef ONLINE_JUDGE freopen ("1.in" ,"r" ,stdin); #endif int t=1 ; cin>>t; while (t--)solve (); return 0 ; }
D. Colorful Stamp 题目描述
题目分析 这个题,就是说对一个数进行操作,每次可以把这个数的十进制某一位作为乘数乘这个数,即为一次操作。问你最小操作次数使这个数变成十进制 n
位。
这个题的话就直接无脑广搜就好了。
标程 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 #include <bits/stdc++.h> #define maxn 200005 #define int unsigned long long using namespace std;int a[maxn];char s[maxn];int target=0 ;int ans=40 ;queue<pair<int ,int >>q; map<int ,int >ma; int bfs (int now) { q.push ({now,0 }); bool used[10 ]; int cnt=0 ; while (q.size ()){ cnt++; memset (used,0 ,sizeof (used)); int num=q.front ().first; int step=q.front ().second; q.pop (); int m=num; if (num>=target){ return step; } while (m){ int p=m%10 ; if (p!=0 &&p!=1 &&!used[p]){ used[p]=1 ; if (ma[p*num]==1 )continue ; ma[p*num]=1 ; q.push ({p*num,step+1 }); } m/=10 ; } } return -1 ; } void solve () { unsigned long long n,x; cin>>n>>x; target=1 ; for (int i=1 ;i<n;i++){ target*=10 ; } int ans=bfs (x); printf ("%lld\n" ,ans); } signed main () { #ifndef ONLINE_JUDGE freopen ("1.in" ,"r" ,stdin); #endif int t=1 ; while (t--)solve (); return 0 ; }
In The End 这波应该是手速场,手速快就是上大分,继上一次罚时爆炸之后这场没有一点罚时,挺好的,刚刚掉蓝一下给加回来了。
100分!