-
思路:快速幂
AC代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e5 + 5; ll qsm(ll a,ll b,int mod){ ll ans = 1; while(b){ if(b&1) ans = ans*a%mod; a = a*a%mod; b >>= 1; } return ans%mod; } int main(void) { ll a,b,m; cin >> a >> b >> m; cout<<qsm(a,b,m)<<endl; return 0; }
-
思路:快速幂
AC代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e5 + 5; const int mod = 200907; ll ksm(ll a,ll b,int mod){ ll ans = 1; while(b){ if(b&1) ans = ans*a%mod; a = a*a%mod; b >>= 1; } return ans; } int main(void) { int t; cin >> t; while(t--){ ll a,b,c,k; cin >> a >> b >> c >> k; if(2*b==a+c){ ll ans = a%mod+((k-1)%mod*(b-a)%mod)%mod; cout<<ans%mod<<endl; }else{ ll q = b/a; ll q1 = q-1; ll qk = ksm(q,k-1,mod); cout<<qk*a%mod<<endl; } } return 0; }
-
题意:小男孩Valera喜欢字符串。当它们是相同的时候,他会更喜欢它们。这就是为什么Valera会在空闲时间玩下面这个游戏。 他有两个由小写字母组成的字符串,根据游戏规则,Valera每次可以将其中一个字符串中的任何一个字母 变为 ,但要支付 的代价。请你输出让两个字符串相同的最小代价,无解输出-1。
思路:首先这道题要注意有坑点,就是不一定 变为 ,可以 变为 , 变为 ,只要转换的代价小即可。无解的两种情况,字符串长度不一样; 无法变成 。有解的情况就是一个Floyd最短路了。
AC代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 500 + 50; int mp[maxn][maxn]; const int INF = 0x3f3f3f3f; int main(void) { string s; string t; cin >> s >> t; int n; cin >> n; for(int i = 0; i < 26; i++){ for(int j = 0; j < 26; j++){ if(i==j) mp[i][j] = 0; else mp[i][j] = INF; } } while(n--){ char u,v; int w; cin >> u >> v >> w; u = u-'a'; v = v-'a'; mp[u][v] = min(mp[u][v],w); } if(s.size()!=t.size()){ cout<<-1<<endl; return 0; } for(int k = 0; k < 26; k++){ for(int i = 0; i < 26; i++){ for(int j = 0; j < 26; j++){ mp[i][j] = min(mp[i][j],mp[i][k]+mp[k][j]); } } } int ans = 0; int len = s.size(); string anss = ""; for(int i = 0; i < len; i++){ if(s[i]==t[i]){ anss += s[i]; } else{ int minn = INF; int u = s[i]-'a'; int v = t[i]-'a'; char tmp; for(int j = 0; j < 26; j++){ if(mp[u][j]+mp[v][j]<minn){ minn = mp[u][j]+mp[v][j]; tmp = j+'a'; } } if(minn==INF){ cout<<-1<<endl; return 0; } anss += tmp; ans += minn; } } cout<<ans<<endl; cout<<anss<<endl; return 0; }
-
题意:有一个由1-n构成的数列,其中部分被删除(删除的元素由0代替),请用被删除的元素补全这个数列,使这个数列中相邻元素奇偶性不同的对数最少。
思路:对比0-1背包,对于每个0,你都可以选择放一个奇数或者放一个偶数,当前状态是由前面的奇偶决定,类似于有向图DAG,所以dp。
dp[i][j][k][2]
第一个状态:每个数字的位置
第二个状态:当前位置的奇数个数
第三个状态:当前位置的偶数个数
第四个状态:当前位置的是奇数还是偶数
AC代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e2 + 10; int dp[maxn][maxn][maxn][2]; int a[maxn]; int main(void) { int n; cin >> n; for(int i = 1; i <= n; i++) cin >> a[i]; memset(dp,0x3f,sizeof(dp)); int odd = n/2+n%2; int even = n/2; dp[0][odd][even][1] = dp[0][odd][even][0] = 0; for(int i = 1; i <= n; i++){ for(int j = 0; j <= odd; j++){ for(int k = 0; k <= even; k++){ if(a[i]&&a[i]%2||a[i]==0){ //放奇数 dp[i][j][k][1] = min(dp[i][j][k][1],dp[i-1][j+1][k][0]+1);//这一个数的上一位是偶数。 dp[i][j][k][1] = min(dp[i][j][k][1],dp[i-1][j+1][k][1]);//这一个数的上一位是奇数。 } if(a[i]&&a[i]%2==0||a[i]==0){//放偶数 dp[i][j][k][0] = min(dp[i][j][k][0],dp[i-1][j][k+1][0]);//这一个数的上一位是偶数。 dp[i][j][k][0] = min(dp[i][j][k][0],dp[i-1][j][k+1][1]+1);//这一个数的上一位是奇数。 } } } } cout<<min(dp[n][0][0][1],dp[n][0][0][0])<<endl; return 0; }
『日常训练』2020WFU个人积分赛第一场
猜你喜欢
转载自blog.csdn.net/wxd1233/article/details/105554943
今日推荐
周排行