首页 > 代码库 > Good Vegetable 4级算法题 分值: [320/3120] 问题: [8/78]
Good Vegetable 4级算法题 分值: [320/3120] 问题: [8/78]
1523 非回文
题目来源: CodeForces基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题收藏关注一个字符串是非回文的,当且仅当,他只由前p个小写字母构成,而且他不包含长度大于等于2的回文子串。
给出长度为n的非回文串s。请找出字典序比s大的,而且字典序要最小的长度为n的非回文。
Input单组测试数据。 第一行有两个整数n 和p (1≤n≤1000; 1≤p≤26)。 第二行包含一个字符串s,它的长度是n。输入保证他是非回文的。Output输出字典序比s大的且字典序要最小的长度为n的非回文,如果不存在输出NO。Input示例样例输入1 3 3 cba 样例输入2 3 4 cbaOutput示例样例输出1 NO 样例输出2 cbd
#include <cstdio> #include <cstring> #include <cmath> #include <queue> #include <vector> #include <string> #include <stack> #include <set> #include <map> #include <iostream> #include <algorithm> using namespace std; #define MP make_pair #define PB push_back typedef long long LL; typedef pair<int,int> Pii; const int inf = 0x3f3f3f3f; const LL INF = 1LL<<60; const int mod = 1000000007; const int N = 1e5+5; const double Pi = acos(-1.0); char s[1005]; int n,p; bool solve(int cur , bool flag){ if(cur==n)return 1; char fix; if(flag){ fix = ‘a‘; } else { fix = s[cur]; if(cur==n-1)fix++; } for(;fix < p;fix++){ if((cur > 0&&fix == s[cur - 1]) || (cur > 1&&fix == s[cur - 2]))continue; if(fix > s[cur])flag=true; s[cur] = fix; if(solve(cur + 1,flag))return true; } return false; } int main() { #ifdef local freopen("in", "r", stdin); #endif cin>>n>>p; p+=‘a‘; cin>>s; if(solve(0,false)){ cout<<s<<endl; } else cout<<"NO"<<endl; }
1655 染色问题
基准时间限制:1 秒 空间限制:10240 KB 分值: 40 难度:4级算法题收藏关注一个n(3<=n<=100)个点的完全图,现在给出n,要求将每条边都染上一种颜色k(1<=k<=n),最终使得所有三个点构成的环(C(n,3)个不同的换)上三条边的颜色和在所有颜色中任选三种颜色的组合(C(n,3)种方案)一一对应,由你来给出染色方案。本题有多组数据Input第一行一个整数T,表示数据组数 接下来T行每行一个整数n,表示完全图的点数Output输出由T个部分组成 每个部分的第一行一个整数n,表示完全图的点数 第二行表示构造结果 如果无解输出No solution 否则输出n*(n-1)/2条边的起点、终点和颜色Input示例2 4 3Output示例4 No solution 3 1 2 3 2 3 1 3 1 2
#include <cstdio> #include <cstring> #include <cmath> #include <queue> #include <vector> #include <string> #include <stack> #include <set> #include <map> #include <iostream> #include <algorithm> using namespace std; #define mp make_pair typedef long long LL; typedef pair<int,int> pii; const int inf = 0x3f3f3f3f; const LL INF = 1LL<<60; const int mod = 1000000007; const int N = 32000; int main() { #ifdef local freopen("in", "r", stdin); #endif int T; cin>>T; while(T--){ int n ; cin>>n; printf("%d\n",n); if(n&1){ for(int i = 1; i < n ; i++){ for(int j = i + 1; j <= n ; j++){ printf("%d %d %d ",i,j,(i+j-3)%n+1); } } } else printf("No solution"); puts(""); } }
1674 区间的价值 V2
基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题收藏关注lyk拥有一个区间。它规定一个区间的价值为这个区间中所有数and起来的值与这个区间所有数or起来的值的乘积。例如3个数2,3,6。它们and起来的值为2,or起来的值为7,这个区间对答案的贡献为2*7=14。现在lyk有一个n个数的序列,它想知道所有n*(n+1)/2个区间的贡献的和对1000000007取模后的结果是多少。例如当这个序列为{3,4,5}时,那么区间[1,1],[1,2],[1,3],[2,2],[2,3],[3,3]的贡献分别为9,0,0,16,20,25。Input第一行一个数n(1<=n<=100000)。 接下来一行n个数ai,表示这n个数(0<=ai<=10^9)。Output一行表示答案。Input示例3 3 4 5Output示例70
#include <cstdio> #include <cstring> #include <cmath> #include <queue> #include <vector> #include <string> #include <stack> #include <set> #include <map> #include <iostream> #include <algorithm> using namespace std; #define MP make_pair #define PB push_back typedef long long LL; typedef pair<int,int> Pii; const int inf = 0x3f3f3f3f; const LL INF = 1LL<<60; const int mod = 1000000007; const int N = 1e5+5; const double Pi = acos(-1.0); const int maxn = 1e5+5; int n ; int a[maxn]; int Or[155],And[155]; int ans[155]; LL res = 0; void cnt(int l , int r){ int mid = (l + r) >> 1; int s = 0 ; Or[s] = And[s] = a[mid]; ans[s] = 1; for(int i = mid + 1; i <= r; i++){ if( ( (Or[s]|a[i]) == Or[s] ) && ( (And[s]&a[i]) == And[s] ) ){ ans[s]++; } else { s++; Or[s] = Or[s - 1] | a[i]; And[s] = And[s - 1] & a[i]; ans[s] = 1; } } int nowor = a[mid] ,nowand = a[mid]; for(int i = mid; i >= l ; i--){ nowor |= a[i]; nowand &= a[i]; for(int j = 0 ; j <= s; j++){ res = (res + ( (1LL * ( nowor | Or[j] ) % mod * ( nowand & And[j] ) )% mod ) * ans[j]) % mod ; } } if(l < mid){ cnt(l , mid - 1); } if(r > mid){ cnt(mid + 1 , r); } } void work() { cin>>n; for(int i = 0 ; i < n ; i++)scanf("%d",&a[i]); cnt(0,n - 1); cout<<res<<endl; } int main() { #ifdef local freopen("in", "r", stdin); #endif work(); }
1509 加长棒题目来源: CodeForces基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题收藏关注现在有三根木棒,他们的长度分别是a,b,c厘米。你可以对他们进行加长(不同的木棒可以增加不同的长度),他们总的加长长度不能超过L厘米。你也可以不对他们进行加长。
现在请你计算一下有多少种加长的方式使得他们能构成合法的三角形(面积非0)。
Input单组测试数据。 共一行,包含4 个整数a,b,c,L (1≤a,b,c≤3*10^5, 0≤L≤3*10^5)。Output输出答案占一行。Input示例1 1 1 2Output示例4
#include <cstdio> #include <cstring> #include <cmath> #include <queue> #include <vector> #include <string> #include <stack> #include <set> #include <map> #include <iostream> #include <algorithm> using namespace std; #define MP make_pair #define PB push_back typedef long long LL; typedef pair<int,int> Pii; const int inf = 0x3f3f3f3f; const LL INF = 1LL<<60; const int mod = 1000000007; const int N = 1e5+5; const double Pi = acos(-1.0); const int maxn = 1e5+5; int a , b , c; int l ; LL res = 0; LL solve(int bigest , int x, int y){ LL ans = 0; int _t = bigest + x + y + l; for(int i = 0 ; i <= l ; i++){ int t = min(_t - bigest - i , bigest + i); if(x + y <= t){ ans += 1LL * (t - x - y + 2) * (t - x - y + 1) / 2; } } return ans ; } void work() { cin>>a>>b>>c>>l; res = 1LL * (l + 3) * (l + 2) * (l + 1) / 6; res -= solve(a,b,c); res -= solve(b,a,c); res -= solve(c,a,b); cout<<res<<endl; } int main() { #ifdef local freopen("in", "r", stdin); #endif work(); }
1491 黄金系统
题目来源: CodeForces基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题收藏关注q在黄金系统下面a0a1...an等于 ∑ni=0ai?q ,其中 ai 是0或者1。
现在给出两个黄金系统下面的数字,请比较他们的大小。
Input单组测试数据。 第一行有一个字符串A。 第二行有一个字符串B。 按照a0到an的顺序输入。 他们都是非空串,可能有前导0,并且只有0和1组成,长度不超过100000。Output如果A>B,输出>; 如果A=B,输出=; 如果A<B,输出<;Input示例00100 11Output示例=
#include <cstdio> #include <cstring> #include <cmath> #include <queue> #include <vector> #include <string> #include <stack> #include <set> #include <map> #include <iostream> #include <algorithm> using namespace std; #define MP make_pair #define PB push_back typedef long long LL; typedef pair<int,int> Pii; const int inf = 0x3f3f3f3f; const LL INF = 1LL<<60; const int mod = 1000000007; const int N = 1e5+5; const double Pi = acos(-1.0); const int maxn = 1e5+5; int cp[maxn]; char A[maxn],B[maxn]; void work(){ cin>>A>>B; int alen = strlen(A),blen = strlen(B); int cplen = max(alen,blen); for(int i = cplen - 1, a = alen - 1,b = blen - 1; i >= 0; i--,a--,b-- ){ cp[i] = (a >= 0 ? A[a] : ‘0‘) - (b >= 0 ? B[b] : ‘0‘); } for(int i = 0; i < cplen - 2 ; i++){ if(cp[i]){ cp[i+1] += cp[i]; cp[i+2] += cp[i]; if(cp[i+1] > 10000000){ cout<<">"<<endl; return; } else if(cp[i+1] < -1000000){ cout<<"<"<<endl; return; } cp[i] = 0; } } if(cp[cplen-2]==0&&cp[cplen-1] == 0){ cout<<"="<<endl; return; } double ans = ( sqrt(5.) + 1 )*cp[cplen-2] / 2 +cp[cplen-1]; if(ans > 0){ cout<<">"<<endl; } else cout<<"<"<<endl; } int main() { #ifdef local freopen("in", "r", stdin); #endif work(); }
1607 卷积和
基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题收藏关注杰西最近在研究卷积,例如一个数字1234,那么经过杰西的变换后,就会变成1*4+2*3+3*2+4*1,例如一个数字是234,那么就会变成2*4+3*3+4*2。
形象化的,我们可以设f(x)表示x经过杰西变换后的值。用公式表示 x=d 那么 f
例如f(1234)=20,f(234)=25。
现在他想到了一个问题。
如果他想知道对于所有i=L~R时的f(i)的值的和,该怎么做呢。
现在这个问题交给了你。
但是这个答案可能会非常大,因此杰西只想知道最终答案对1000000007取模后的答案。
Input单组测试数据 一行两个整数L,R(1<=L<=R<=10^18)。Output一个数表示答案。Input示例3 233Output示例8730
#include <cstdio> #include <cstring> #include <cmath> #include <queue> #include <vector> #include <string> #include <stack> #include <set> #include <map> #include <iostream> #include <algorithm> using namespace std; #define MP make_pair #define PB push_back typedef long long LL; typedef pair<int,int> Pii; const int inf = 0x3f3f3f3f; const LL INF = 1LL<<60; const int mod = 1000000007; const int N = 1e5+5; const double Pi = acos(-1.0); const int maxn = 1e5+5; LL ztt = 285;//1^2 + 2^2 + 3^2……+9^2 LL tp[25]; LL sum[25]; LL cnt[25];//有前导0 LL all[25];//无前导0 int base[65]; int len = 0; void add(LL &a,LL b) { a += b; if(a >= mod)a -= mod; } LL dfs(int cur) { LL res = 0; if(!cur) { for(int i = len; i; i--) { add(res,base[i]*base[len-i+1]); } return res; } for(int i = (cur==len); i < base[cur]; i++) { for(int j = len ; j; j--) { int k = len - j + 1; if(j > cur) { if(k > cur)add(res,(base[j] * base[k] * tp[cur-1]) % mod); else if(k == cur)add(res,(base[j] * i * tp[cur-1]) % mod); else add(res,(base[j] * 45 * tp[cur-2]) % mod); } else if(j == cur){ if(k > cur)add(res,(base[k] * i * tp[cur-1]) % mod); else if(k == cur)add(res,(i * i * tp[cur-1]) % mod); else add(res,(i * 45 * tp[cur-2]) % mod); } else { if(k > cur)add(res,(base[k] * 45 * tp[cur-2]) % mod); else if(k == cur)add(res,(i * 45 * tp[cur-2]) % mod); else { if(j == k)add(res,(ztt * tp[cur-2]) % mod); else add(res,(45 * 45 * tp[cur-3]) % mod); } } } } return (res + dfs(cur - 1)) % mod; } LL solve(LL x) { if(x < 0)return 0; len = 0; for(; x; x/=10) { base[++len] = x%10; } return (dfs(len) + sum[len-1]) % mod; } void work() { LL r,l; cin>>l>>r; cout<<(solve(r) - solve(l-1) + mod) % mod<<endl; } void init() { cnt[0] = all[0] = 0; cnt[1] = all[1] = ztt; tp[0] = 1; tp[1] = 10; for(int i = 2; i < 19; i++) { tp[i] = (tp[i-1] * 10) % mod; all[i] = ((cnt[i-2] * 9 * 10)%mod + (45 * 45 * 2 * tp[i-2]) % mod) % mod; cnt[i] = ((cnt[i-2] * 10 * 10)%mod + (45 * 45 * 2 * tp[i-2]) % mod) % mod; } for(int i = 1; i < 19; i++) { sum[i] = (sum[i-1] + all[i]) % mod; } } int main() { #ifdef local freopen("in", "r", stdin); #endif init(); work(); }
1503 猪和回文
题目来源: CodeForces基准时间限制:2 秒 空间限制:131072 KB 分值: 40 难度:4级算法题收藏关注一只猪走进了一个森林。很凑巧的是,这个森林的形状是长方形的,有n行,m列组成。我们把这个长方形的行从上到下标记为1到n,列从左到右标记为1到m。处于第r行第c列的格子用(r,c)表示。
刚开始的时候猪站在(1,1),他的目标是走到(n,m)。由于猪回家心切,他在(r,c)的时候,只会往(r+1,c)或(r,c+1)走。他不能走出这个森林。
这只猪所在的森林是一个非同寻常的森林。有一些格子看起来非常相似,而有一些相差非常巨大。猪在行走的过程中喜欢拍下他经过的每一个格子的照片。一条路径被认为是漂亮的当且仅当拍下来的照片序列顺着看和反着看是一样的。也就是说,猪经过的路径要构成一个回文。
数一数从(1,1)到(n,m)有多少条漂亮路径。答案可能非常巨大,请输出对 109+7 取余后的结果。
样例解释:有三种可能
Input单组测试数据。 第一行有两个整数 n,m (1≤n,m≤500),表示森林的长和宽。 接下来有n行,每行有m个小写字母,表示每一个格子的类型。同一种类型用同一个字母表示,不同的类型用不同的字母表示。Output输出答案占一行。Input示例3 4 aaab baaa abbaOutput示例3
#include <cstdio> #include <cstring> #include <cmath> #include <queue> #include <vector> #include <string> #include <stack> #include <set> #include <map> #include <iostream> #include <algorithm> using namespace std; #define MP make_pair #define PB push_back typedef long long LL; typedef pair<int,int> Pii; const int inf = 0x3f3f3f3f; const LL INF = 1LL<<60; const int mod = 1000000007; const int N = 1e5+5; const double Pi = acos(-1.0); const int maxn = 1e5+5; char maz[505][505]; LL dp[2][505][505]; int n , m; void update(LL &a,LL b) { a += b; if(a >= mod)a -= mod; } void work() { int s = 0; int half = (n + m) >> 1; dp[s][1][n] = (maz[1][1] == maz[n][m]); for(int i = 2 ; i <= half; i++) { s^=1; memset(dp[s],0,sizeof(dp[s])); for(int x = 1 ; x <= n && x <= i; x++) { for(int _x = n; _x > 0 && _x >= n - i + 1 ; _x--) { int y = i - x + 1; int _y = m + n + 1 - i - _x; if(maz[x][y]!=maz[_x][_y])continue; // cout<<"-----"<<endl; // cout<<i<<endl; // cout<<x<<" "<<y<<endl; // cout<<_x<<" "<<_y<<endl; // cout<<"-----"<<endl; update(dp[s][x][_x],dp[s^1][x][_x]); update(dp[s][x][_x],dp[s^1][x-1][_x]); update(dp[s][x][_x],dp[s^1][x-1][_x+1]); update(dp[s][x][_x],dp[s^1][x][_x+1]); } } } LL res = 0; if((n+m+1) & 1) { for(int x = 1; x <= n; x++) { for(int _x = n ; _x ; _x--) { int y = half - x + 1; int _y = m + n + 1 - half - _x; if(x==_x&&y==_y) update(res,dp[s][x][_x]); } } } else { for(int x = 1; x <= n; x++) { for(int _x = n ; _x ; _x--) { int y = half - x + 1; int _y = m + n + 1 - half - _x; if(x==_x||y==_y) update(res,dp[s][x][_x]); } } } cout<<res<<endl; } void init() { cin>>n>>m; for(int i = 1; i <= n; i++)scanf("%s",maz[i]+1); } int main() { #ifdef local freopen("in", "r", stdin); #endif init(); work(); }
1487 占领资源题目来源: TopCoder基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题收藏关注有一个矩形区域被划分为N行M列的网格,每个格子里有一定数量的资源并记录在矩阵val中,坐标(x,y)位置上资源量为val[x][y],其val中每个元素的值为0~9的整数。如果你在某个网格(a,b)上造一座保护塔,那么你可以占领K个网格中的资源,这K个格子分别是(a+dx[1],b+dy[1]),(a+dx[2],b+dy[2]),...,(a+dx[K],b+dy[K]),注意(a,b)这格本身可能未必会被占领。现在你能建造不超过2个塔,问最多能占领多少资源?一个网格被多个塔占领时其资源只计算一次。另外如果计算的位置(a+dx[i],b+dy[i])在网格外,则不贡献任何资源。Input多组测试数据,第一行一个整数T,表示测试数据数量,1<=T<=5 每组测试数据有相同的结构构成: 每组数据第一行三个整数N,M,K,其中2<=N,M<=100,1<=K<=10。 之后会有N行,每行M个元素,表示val矩阵。每个元素为0~9,占一个字符,元素间没空格。 再接下来有K行,每行两个整数dx[i]与dy[i],其中-(N-1)<=dx[i]<=N-1,-(M-1)<=dy[i]<=(M-1).Output每组数据一行输出,即可占领的最大资源总量。Input示例3 2 2 2 11 11 0 0 0 1 2 2 2 11 11 0 0 1 1 2 2 1 15 61 0 0Output示例4 3 11
#include <cstdio> #include <cstring> #include <cmath> #include <queue> #include <vector> #include <string> #include <stack> #include <set> #include <map> #include <iostream> #include <algorithm> using namespace std; #define MP make_pair #define PB push_back typedef long long LL; typedef pair<int,int> Pii; const int inf = 0x3f3f3f3f; const LL INF = 1LL<<60; const int mod = 1000000007; const int N = 1e5+5; const double Pi = acos(-1.0); const int maxn = 1e5+5; char maz[105][105]; int id[105][105]; bool vis[105][105]; int n,m,k; int ros[10005]; int tol; int dx[15],dy[15]; int ne[105]; int rmq[10005][25]; int ans; bool judge(int x,int y) { return x >= 0 && y >= 0 && x < n && y < m; } void init_rmq() { int l = (log((double)tol)/log(2.)); for(int i = 0; i < tol; i++)rmq[i][0] = ros[i]; for(int j = 0 ; j < l; j++) { for(int i = 0 ; (i + (1 << j) ) < tol; i++) { rmq[i][j+1] = max(rmq[i][j],rmq[i+(1<<j)][j]); } } } int get_Max(int l ,int r) { int len = r - l + 1; len = log((double)len)/log(2.); int res = max(rmq[l][len],rmq[r-(1<<len)+1][len]); // cout<<l<<" "<<r<<endl; // cout<<res<<endl; return res; } void work() { for(int i = 0 ; i < tol; i++) { int nes = 0; int x = i / m,y = i % m; for(int j = 0 ; j < k; j++) { int nx = x + dx[j],ny = y +dy[j]; if(!judge(nx,ny))continue; vis[nx][ny] = 1; for(int z = 0 ; z < k ; z++) { int xx = nx - dx[z],yy = ny - dy[z]; if(judge(xx,yy)) { ne[nes++] = id[xx][yy]; } } } ne[nes++] = -1; ne[nes++] = tol; sort(ne,ne+nes); nes = unique(ne,ne+nes) - ne; int res = 0; for(int _i = 0; _i < nes - 1; _i++) { if((ne[_i] + 1) <= (ne[_i+1] - 1)) { res = max(res,get_Max(ne[_i] + 1 , ne[_i+1] - 1)); } } // for(int i = 0 ; i < nes;i++)printf("%d ",ne[i]); // cout<<endl; // cout<<ros[i]<<endl; // cout<<res<<endl; // cout<<"-----"<<endl; for(int _i = 1 ; _i < nes - 1; _i++) { int _res = 0; int ID = ne[_i]; int _x = ID / m,_y = ID % m; for(int j = 0 ; j < k; j++) { int nx = _x + dx[j],ny = _y +dy[j]; if(!judge(nx,ny)||vis[nx][ny])continue; _res += maz[nx][ny] - ‘0‘; } res = max(res,_res); } for(int j = 0 ; j < k; j++) { int nx = x + dx[j],ny = y + dy[j]; if(!judge(nx,ny))continue; vis[nx][ny] = 0; } ans = max(ans,ros[i] + res); } cout<<ans<<endl; } void init() { memset(ros,0,sizeof ros); tol = 0; ans = 0; cin>>n>>m>>k; for(int i = 0 ; i < n ; i++) { scanf("%s",maz[i]); for(int j = 0; j < m ; j++) { id[i][j] = tol++; } } for(int i = 0 ; i < k ; i++) { scanf("%d%d",&dx[i],&dy[i]); } for(int i = 0 ; i < tol; i++) { int x = i / m,y = i % m; for(int j = 0 ; j < k; j++) { int nx = x + dx[j],ny = y + dy[j]; if(!judge(nx,ny))continue; ros[i] += maz[nx][ny] - ‘0‘; } } init_rmq(); // cout<<rmq[0][1]<<endl; } int main() { #ifdef local freopen("in", "r", stdin); #endif int T; cin>>T; while(T--) { init(); work(); } }
Good Vegetable 4级算法题 分值: [320/3120] 问题: [8/78]