DPS
无
#include
#include
#include
#include
using namespace std;
// #define TDS_ACM_LOCAL
const int N=109;
typedef long long ll;
ll n, a[N], mx=0;
void solve(ll d){
cout<<"+";
int s=ceil((50.0*d)/mx);
for(int i=0; i<s; i++) cout<<"-";
cout<<"+\n|";
for(int i=0; i<s-1; i++) cout<<" ";
if(s!=0) cout<< (d==mx ? "*":" ");
cout<<"|"<<d<<endl;
cout<<"+";
for(int i=0; i<s; i++) cout<<"-";
cout<<"+\n";
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
#ifdef TDS_ACM_LOCAL
freopen("D:\\VS code\\.vscode\\testall\\in.txt", "r", stdin);
freopen("D:\\VS code\\.vscode\\testall\\out.txt", "w", stdout);
#endif
cin>>n;
for(int i=0; i<n; i++){
cin>>a[i];
if(a[i]>mx) mx=a[i];
}
for(int i=0; i<n; i++) solve(a[i]);
return 0;
}
Hard Math Problem
直接看官方题解吧
• (i+j)%3 =0 交错2和3 • 答案是2/3
• 因为这样每个1旁边恰好有一个2和3,而任意两个2和3不相邻。
• 可以计算出这是上限。
#include
int main(){
printf("0.666667\n");
return 0;
}
Bogo Sort
首先对题意进行大致说明,就是将一个数组按照题目给的数组的方式进行置换,也就是置换群的变换
1、求出每个环的长度和环的个数
2、求所有环的lcm,但是很明显爆long long了,所有可以采取高精乘低精的方法,求出所有数字中出现的素数的个数,然后乘起来。
#include
#include
using namespace std;
#define INF 0x3f3f3f3f
// #define TDS_ACM_LOCAL
const int N=1e5 + 9;
int pvis[N], vis[N];
int prime[N], psum;
int n, a[N], loop[N], sum, pm[N], k, len, ans[N];
void mul(int x){
for(int i=1;i<=len;i++) ans[i]*=x;
for(int i=1;i<len;i++)if(ans[i]>9) ans[i+1]+=ans[i]/10,ans[i]%=10;
while(len<n&&ans[len]>9) ans[len+1]+=ans[len]/10,ans[len++]%=10;
ans[len+1]=0;
}//高精乘低精
void isprime() //埃氏筛素数打表
{
pvis[1]=1;
for(int i=2;i<N;i++){
if(!pvis[i]) prime[psum++]=i;
for(int j=i*2; j<N; j+=i)pvis[j]=1;
}
}
void solve(){
isprime();
cin>>n;
for(int i=1; i<=n; i++) cin>>a[i];
for(int i=1; i<=n; i++){ //求数组中环的个数和每个环的长度
if(!vis[i]){
loop[++sum]=1; //loop存环的长度,sum为个数
vis[i]=1;
for(int j=a[i]; j!=i; j=a[j]){
loop[sum]++;
vis[j]=1;
}
}
}
for(int i=1; i<=sum; i++){ //求得所有环长包含的素数的个数的最大值
for(int j=0; j<psum && loop[i]>1; j++){
k=0;
while(loop[i]%prime[j]==0) loop[i]/=prime[j], k++;
pm[prime[j]]=max(pm[prime[j]], k); //pm存出现的素数的最大个数
}
}
len=1, ans[1]=1; //高精乘低精的准备工作
for(int i=0; i<psum; i++) while(pm[prime[i]]--) mul(prime[i]);
for(int i=len; i>=1; i--) cout<<ans[i]; //倒序输出
cout<<endl;
return ;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
#ifdef TDS_ACM_LOCAL
freopen("D:\\VS code\\.vscode\\testall\\in.txt", "r", stdin);
freopen("D:\\VS code\\.vscode\\testall\\out.txt", "w", stdout);
#endif
solve();
return 0;
}
Drop Voicing
1、第一种操作将倒数第二个移到最前面,花费1
2、第二种操作将第一个移到最后面,花费0
我们可以将这整个序列视作一个头尾相连的环
很明显的我们可以使用2操作到达任何位置,但其不能对环的顺序造成影响
因为操作二可以到达任意位置,所以操作一可以将任意位置数放在任意位置,对环顺序有有影响但花费1
为了使得花费尽可能的小,所以我们应该尽可能的找到一个升序排列尽可能多的数(最长上升子序列LIS)
求得最大LIS的长度后,剩下的数字即为需要改变的,即为最小花费
#include
#include
#include
using namespace std;
const double pi = acos(-1.0);
#define INF 0x3f3f3f3f
// #define TDS_ACM_LOCAL
const int N=1e3 +9;
int f[N];
int n, a[N], ans;
int Lis(int l,int r)
{
int ans=0;
f[++ans]=a[l];
for(int i=l+1;i<=r;i++)
{
if(a[i]>f[ans])
{
f[++ans]=a[i];
continue;
}
int pos=lower_bound(f+1,f+1+ans,a[i])-f;
f[pos]=a[i];
}
return ans;
}
void solve(){
cin>>n;
for(int i=1; i<=n; i++){
cin>>a[i];
a[i+n]=a[i];
}
for(int i=1; i<=n; i++) ans=max(ans, Lis(i, i+n-1));
cout<<n-ans<<endl;
return ;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
#ifdef TDS_ACM_LOCAL
freopen("D:\\VS code\\.vscode\\testall\\in.txt", "r", stdin);
freopen("D:\\VS code\\.vscode\\testall\\out.txt", "w", stdout);
#endif
solve();
return 0;
}