Educational Codeforces Round 54 (Rated for Div. 2)A B C D
阿新 • • 發佈:2018-12-21
題意:問最多刪去一個字元,如何變為字典序最小的串。 題解:明顯是貪心了,從前往後刪,找到第一個的刪去即可。找不到就刪去最後一個字元。
#include<bits/stdc++.h>
using namespace std;
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.in","r",stdin);
#endif
int n;
string s;
cin>>n>>s;
string t = "";
for(int i = 0; i < s.length(); ++i){
if(i == 0 && s[0] > s[1]) {
t = s.substr(1,s.length());
break;
}
if(i == n - 1) {
t = s.substr(0,s.length() - 1);
break;
}
if(s[i] > s[i + 1]) {
t = s.substr(0,i) + s.substr(i + 1,s.length());
break;
}
}
cout<< t <<endl;
return 0;
}
程式碼
題意:不斷減去最小當前值的最小質因子,問最後變為至少需要多少次。 題解:
很容易發現如果是質數,只要減一次即可; 如果是偶數只需要減次; 如果是奇數,就強行暴力減成偶數,再直接算出來即可。
程式碼
#include<bits/stdc++.h>
using namespace std;
const int N = 100100;
int prime[N];
bool vis[N];
int init()
{
int k = 0;
for(int i = 2; i < N; ++i) {
if(vis[i] == 0) {
prime[k++] = i;
}
for(int j = 2; j * i < N; ++j) {
if(vis[i * j] == 0) {
vis[i * j] = 1;
}
}
}
return k;
}
bool isPrime(long long n)
{
for(int i = 2; 1LL * i * i <= n; ++i) {
if(n % i == 0) return 0;
}
return 1;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.in","r",stdin);
#endif
long long n;
int cnt = init();
long long ans = 0;
cin>>n;
if(isPrime(n)) {
cout<<1<<endl;
return 0;
}
if(n % 2 == 0) {
cout<<n / 2<<endl;
return 0;
}
for(int i = 0; i < cnt; ++i) {
while(n % prime[i] == 0) {
if(n - prime[i] >= 0)
n -= prime[i];
ans++;
if(n % 2 == 0) {
ans += n / 2;
n = 0;
break;
}
//cout<<prime[i]<<endl;
if(n == 0) break;
}
if(n == 0) break;
}
cout<< ans <<endl;
return 0;
}
題意:問滿足的和。 題解:首先容易發現明顯是個二元一次方程,所以解一下就會發現的範圍在,然後二分即可。
程式碼
#include<bits/stdc++.h>
using namespace std;
int d;
long double ans = 0;
bool love(long double x)
{
if(x * ((long double)d - x) > d) {
return 1;
}
return 0;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.in","r",stdin);
#endif
int t;
cin>>t;
while(t--) {
cin>>d;
int f = 0;
long double l = d - 2, r = d;
if(d < 4) {
if(d == 0) {
printf("Y %.9f %.9f\n",0.0,0.0);
continue;
}else{
printf("N\n");
continue;
}
}
if(d >= 4)
while(l < r) {
long double mid = (l + r) / 2, a = mid, b = d - mid;
if(fabs(a * b - d) <= 1e-7) {
ans = mid;
break;
}
if(love(mid))
l = mid;
else
r = mid;
}
if(ans){
printf("Y %.9f %.9f\n",(double)ans,(double)(d-ans));
}else{
printf("N\n");
}
}
return 0;
}
題意:個點條邊,最多保留條邊,問最後在保證最短路徑不變並且點儘可能多的情況下的圖中剩餘的路徑編號。 題解:首先通過跑一遍,得出來的最短路徑一定是一棵樹,所以為了點儘可能多隻要保留最先找到的條邊即可。
程式碼
#include<bits/stdc++.h>
typedef long long LL;
using namespace std;
#define Pii pair<LL,int>
#define P pair<LL,Pii>
const int N = 300100;
int n,m,k,from[N];
LL dis[N];
vector<int> ans;
vector<P> E[N];
void dijkstra(int s)
{
memset(dis,0x3f3f,sizeof dis);
dis[s] = 0;
priority_queue<Pii, vector< Pii >, greater< Pii > > pq;
pq.push({dis[s],s});
int cnt = 0;
while(cnt < k && !pq.empty()) {
Pii cur = pq.top();
pq.pop();
LL d = cur.first;
int u = cur.second;
if(dis[u] < d) continue;
if(u != 1) {
cnt++;
ans.push_back(from[u]);
}
for(P t : E[u]) {
LL w = t.first;
int f = t.second.second, v = t.second.first;
if(dis[v] > dis[u] + w) {
dis[v] = dis[u] + w;
from[v] = f;
pq.push({dis[v],v});
}
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.in","r",stdin);
#endif
int x,y,w;
cin>>n>>m>>k;
for(int i = 1; i <= m; ++i) {
cin>>x>>y>>w;
E[x].push_back({w,{y,i}});
E[y].push_back({w,{x,i}});
}
dijkstra(1);
cout << ans.size() << endl;
for(int iter : ans) {
cout<< iter << ' ';
}
cout<<endl;
return 0;
}