L、Problem L is the Only Lovely Problem
签到题,字符串处理,注意不区分大小写就是了。
s = input().lower() if len(s)<6: print('ugly') else: if s[:6] == 'lovely': print('lovely') else: print('ugly')
B、Classical String Problem
给出一个起始字符串,n次操作,一种是修改,正数就从前面x个字符串分隔整体换位置。
一种是查询,问当前操作中的字符串第x个字符是什么,下标1开始,输入均合法。
解题思路:抓住分隔整体换位置这个要点,最开始写的python字符串切片取硬模拟,果不其然的TLE了。
那么模拟不行,换个办法?整体分隔,再换位置,你会发现,只有起始的头下标变了,n后面接着还是1,1后面接2。
如果你再换,把2换到开头,1过了还是2,2过了就是3,无论怎么写样例你会发现,只有开头在动,整体字符串的相对位置都是保持不动的。
得出这个结论的要点在于整体移动不改变相对性。这样的话就会有一种O(T)的做法,直接取模维护起点下标既可。
使用cin记得关掉和scanf的兼容)巨量数据建议还是putchar什么的。
#pragma GCC target("avx,sse2,sse3,sse4,popcnt") #pragma GCC optimize("O2,O3,Ofast,inline,unroll-all-loops,-ffast-math") #include <bits/stdc++.h> using namespace std; #define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0) #define all(__vv__) (__vv__).begin(), (__vv__).end() #define endl "\n" #define pai pair<int, int> #define mk(__x__,__y__) make_pair(__x__,__y__) #define ms(__x__,__val__) memset(__x__, __val__, sizeof(__x__)) typedef long long ll; typedef unsigned long long ull; typedef long double ld; const int MOD = 1e9 + 7; const int INF = 0x3f3f3f3f; inline ll read() { ll s = 0, w = 1; char ch = getchar(); for (; !isdigit(ch); ch = getchar()) if (ch == '-') w = -1; for (; isdigit(ch); ch = getchar()) s = (s << 1) + (s << 3) + (ch ^ 48); return s * w; } inline void print(ll x) { if (!x) { putchar('0'); return; } char F[40]; ll tmp = x > 0 ? x : -x; if (x < 0)putchar('-'); int cnt = 0; while (tmp > 0) { F[cnt++] = tmp % 10 + '0'; tmp /= 10; } while (cnt > 0)putchar(F[--cnt]); } inline ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; } ll qpow(ll a, ll b) { ll ans = 1; while (b) { if (b & 1) ans *= a; b >>= 1; a *= a; } return ans; } ll qpow(ll a, ll b, ll mod) { ll ans = 1; while (b) { if (b & 1)(ans *= a) %= mod; b >>= 1; (a *= a) %= mod; }return ans % mod; } inline int lowbit(int x) { return x & (-x); } const int N = 1e5 + 7; string s; int main() { js; int T, x, st = 0; cin >> s >> T; int len = s.size(); while (T--) { char op; cin >> op >> x; if (op == 'A') cout << s[(st + x - 1) % len] << endl; else st = (st + x + len) % len; //记录开头的下标即可 } return 0; }
A、Clam and Fish
队友切掉的)队友太顶了
题目描述大概是,有四种模式,分别是
0代表的没鱼没蚯蚓 1代表的没鱼有蚯蚓 2代表的有鱼没蚯蚓 3代表的有鱼有蚯蚓
下面给出你的每一步模式,如果这一步选择了捕鱼可以直接鱼数目加1,否则蚯蚓可以花费一个回合做成鱼饵,如果这个回合没有鱼但是你手上有鱼饵的话,还是可以让你的鱼数目加1。
问题:如何再给定每天模式的情况下,让最后一天钓上来的鱼数目最多。
解题思路:首先是一个最基本的贪心思路,我们需要得到最多的鱼,这一天如果是2,3两种状态的话,肯定想也不想直接捕鱼,2不多说,3的话你做鱼饵再钓鱼用2天时间,肯定比不上你这一天直接钓鱼来的实在。也就是满足了我现在的选择肯定不会比别的选择差这一条贪心策略。
剩下就是0,1两种模式,0的话肯定也不多说,直接由鱼饵就钓鱼,没有就空过,关键在于1状态如何处理让答案最大。
我们可以统计出后一天开始没有鱼钓的天数,如果现在拥有的鱼饵数大于等于后一天开始没有鱼钓天数,说明现在继续囤积鱼饵也用不出去,这天选择用掉鱼饵,但是如果我当前的鱼饵数不够后一天开始没有鱼钓的天数,那我就现在开始尽可能多的囤积鱼饵,反正在后续的天数内,上钓的鱼数目是相同的,也满足了贪心中最起码不必别人差的策略。
那么最后还要统计出后一天到最后没有鱼掉的天数,可以用倒序遍历方法,求个后缀和就行。
不得不说是一个很好的贪心题目,好在队友想到解决方法了。
#pragma GCC target("avx,sse2,sse3,sse4,popcnt") #pragma GCC optimize("O2,O3,Ofast,inline,unroll-all-loops,-ffast-math") #include<bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; #define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0) inline void write(__int128 x) { if (!x) { putchar('0'); return; } char F[50]; __int128 tmp = x > 0 ? x : -x; if (x < 0)putchar('-'); int cnt = 0; while (tmp > 0) { F[cnt++] = tmp % 10 + '0'; tmp /= 10; } while (cnt > 0)putchar(F[--cnt]); } #define pb push_back #define pll pair<ll,ll> #define INF 0x3f3f3f3f const int mod = 1e9+7; const int maxn = 55; #define stop system("pause") #define PI acos(-1.0) inline ll read(){ ll s = 0, w = 1; char ch = getchar(); while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); } while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar(); return s * w; } int num[2000005]; char s[2000005]; int main(){ int t = read(); while(t--){ int n = read(); scanf("%s",s); int ans = 0,yue = 0; num[n] = 0; for(int i = n-1 ; i >=0 ; --i){ if(s[i] =='1' ||s[i] == '0') num[i] = num[i+1] +1; else num[i] = num[i+1]; } for(int i = 0 ; i < n ; ++i){ if( s[i] == '0' && yue) ++ans,--yue; else if(s[i] == '1'){ if(yue > 0 && yue >= num[i+1]) --yue,++ans; //注意细节,别出-1的鱼饵数了 else ++yue; } else if(s[i] == '2' || s[i] == '3') ++ans; } printf("%d\n",ans); } }
C、Operation Love
给出20个二维平面的点,可能是浮点数,但是顺序或者倒序连接之后一定是图中左手或者右手的图案。
并且保证,图形只做旋转和平移,不做放缩处理。
需要我们判断他给出的图像是左手还是右手?
解题思路:通过向量的叉乘判断顺逆时针,这个题目我觉得难点就这一个)如果除开精度来说的话……1e-6卡了3下,1e-2就A了
如果你判断出了顺逆时针,那么我还多写了一步,把长度复制一倍,怕他给出的起点不是最左下的点或者最右下的点。
这样连接之后,求下两两之间的距离,找出最长的9所在下标,直接判断顺时针下9下一条边应该长度为几,就可以出左右手了,逆时针同理。
具体判断三点的顺逆性可以去百度,公式也很简单)不记得寒假那本算法书讲过,使用有点印象就写出这题来了。
#pragma GCC target("avx,sse2,sse3,sse4,popcnt") #pragma GCC optimize("O2,O3,Ofast,inline,unroll-all-loops,-ffast-math") #include <bits/stdc++.h> using namespace std; #define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0) #define all(__vv__) (__vv__).begin(), (__vv__).end() #define endl "\n" #define pai pair<double, double> #define mk(__x__,__y__) make_pair(__x__,__y__) #define ms(__x__,__val__) memset(__x__, __val__, sizeof(__x__)) typedef long long ll; typedef unsigned long long ull; typedef long double ld; const int MOD = 1e9 + 7; const int INF = 0x3f3f3f3f; inline ll read() { ll s = 0, w = 1; char ch = getchar(); for (; !isdigit(ch); ch = getchar()) if (ch == '-') w = -1; for (; isdigit(ch); ch = getchar()) s = (s << 1) + (s << 3) + (ch ^ 48); return s * w; } inline void print(ll x) { if (!x) { putchar('0'); return; } char F[40]; ll tmp = x > 0 ? x : -x; if (x < 0)putchar('-'); int cnt = 0; while (tmp > 0) { F[cnt++] = tmp % 10 + '0'; tmp /= 10; } while (cnt > 0)putchar(F[--cnt]); } inline ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; } ll qpow(ll a, ll b) { ll ans = 1; while (b) { if (b & 1) ans *= a; b >>= 1; a *= a; } return ans; } ll qpow(ll a, ll b, ll mod) { ll ans = 1; while (b) { if (b & 1)(ans *= a) %= mod; b >>= 1; (a *= a) %= mod; }return ans % mod; } inline int lowbit(int x) { return x & (-x); } const int N = 50; const double eps = 1e-2; pai a[N]; #define x first #define y second struct Node { int dis; int id; bool operator < (const Node& A) const { if (dis != A.dis) return dis > A.dis; return id > A.id; } }b[N]; int main() { js; int T; cin >> T; while (T--) { for (int i = 1; i <= 20; ++i) { cin >> a[i].x >> a[i].y; a[20 + i] = a[i]; } for (int i = 2; i <= 40; ++i) { b[i].dis = fabs(sqrt((a[i].x - a[i - 1].x) * (a[i].x - a[i - 1].x) + (a[i].y - a[i - 1].y) * (a[i].y - a[i - 1].y))) + eps; b[i].id = i; } int cnt = 0, pos = -1; for (int i = 2; i <= 40; ++i) { if (b[i].dis == 9) { pos = i; break; } } int flag = 0; if ((a[pos].x - a[pos - 1].x) * (a[pos + 1].y - a[pos].y) - (a[pos + 1].x - a[pos].x) * (a[pos].y - a[pos - 1].y) < 0) { //向量叉乘,小于零顺时针 flag = 1; } //否则逆时针 if (flag) { if (b[pos + 1].dis == 6) cout << "right" << endl; else cout << "left" << endl; } else { if (b[pos + 1].dis == 6) cout << "left" << endl; else cout << "right" << endl; } } return 0; }