ZJUT第19届“杭银理财杯”补题

第一次三人一台电脑的正式比赛,弱队和更弱的队长wwwww

讲真这种比赛我一直以为除了个别签到题不需要算法之外其他的都是算法数据结构嵌套,但是这次比赛感觉出了好多有点思维的题,思维程度还是太菜了

因为没有保存当时的AC代码,就只放补的题咯

ZJUT第19届“杭银理财杯”补题_第1张图片

给出三种操作, 在字符串中插入一个字母,删除一个字母,改变一个字母,定义d(A,B)是由字符串A到B所需要的最少操作次数,给出字符串S,T,问找出一个字符串R,使得d(S,R)+d(T,R)最小。

思路:我们可以观察这个式子是什么意思:存在一个字符串R,使得S->R->T的操作次数最小。这个R的取值就是从S到T的任意一个中间态,因为S和T也是中间态,所以最简单的就是输出S或T即可。

AC代码:

#include

typedef long long ll;
#define INF 0x3f3f3f3f

const double PI=acos(-1);
const double eps=1e-6;
const int mod=1e9+7;
const int N=1e6+5;
std::string s,t;

int main(){
//	freopen("test.in","r",stdin);
//  freopen("output.in", "w", stdout);
    std::cin>>s>>t;
    std::cout<

os:没想到啊没想到,,我是菜比

ZJUT第19届“杭银理财杯”补题_第2张图片

 给出每个点的到达能量,从第i个点到第j个点需要的能量是(j-i)^3*a[j],问从第一个点到最后一个点所需的最少能量是多少。

思路:一开始考虑的是最短路,结果发现数据范围只建图就会炸,后来考虑DP,然后觉得DP是n^2的时间复杂度也不行,就,,,实际上确实是用DP,但是根据这个计算式发现,如果两个点距离相差的差值d的立方大于数据范围1e5后对答案的影响就仅有这个立方了,(更正确的解释是采用极限数据算出这个范围)也就没必要考虑了,这样我们可以把时间复杂度降到1e5*600(600这个数是任取的,取的稍大一点即可),就完全可以过了,DP的过程很简单。

AC Code:

#include

typedef long long ll;
#define INF 0x3f3f3f3f

const double PI=acos(-1);
const double eps=1e-6;
const int mod=1e9+7;
const int N=1e5+5;
ll n,a[N];
ll f[N];

int main(){
//	freopen("test.in","r",stdin);
//  freopen("output.in", "w", stdout);
    std::cin>>n;
    for(ll i=1;i<=n;i++){
        std::cin>>a[i];
    }
    f[1]=0;
    for(ll i=2;i<=n;i++){
        f[i]=1e18;
        for(ll j=std::max(i-600,(ll)1);j<=i-1;j++){
            f[i]=std::min(f[i],f[j]+(i-j)*(i-j)*(i-j)*a[i]);
        }
    }
    std::cout<

 os:DP还能这样优化,,,就是说根本对这个不够敏感,,唉

ZJUT第19届“杭银理财杯”补题_第3张图片

P[i]指的是第i个素数,找到满足给出式子的答案x的个数。

ZJUT第19届“杭银理财杯”补题_第4张图片

 AC Code:

#include

typedef long long ll;
#define INF 0x3f3f3f3f

const double PI=acos(-1);
const double eps=1e-6;
const int mod=1e9+7;
const int N=1e5+5;
ll n;

int main(){
//	freopen("test.in","r",stdin);
//  freopen("output.in", "w", stdout);
    std::cin>>n;
    if(n<2431) std::cout<<0<<'\n';
    else std::cout<<1<<'\n';
	return 0;
}

os:看好几个博客说是打表得出来的,,,这怎么打表啊。现在见到数论相关的题还是很懵,这一部分的练习太少,需要注意。

ZJUT第19届“杭银理财杯”补题_第5张图片

给一棵树的节点上色,上色的要求是不能有多于一个ugly vertex,ugly vertex的定义是:本身是黑色节点,周围节点至少有一个白色节点,至多有一个黑色节点,问怎样上色可以满足要求。

思路:因为仅能有一个ugly vertex,所以我们可以从叶节点开始涂色,把叶节点视为根节点,DFS搜索上色,这样涂色每次只是父节点被上色了,而子节点都是白色,这个节点会是唯一一个ugly vertex。

代码实现:1、复习一个点,对于一棵有n个节点的树,有n-1条边;2、建树可以使用vector数组存图;3、度为1的点为叶节点。

AC Code:

#include

typedef long long ll;
#define INF 0x3f3f3f3f

const double PI=acos(-1);
const double eps=1e-6;
const int mod=1e9+7;
const int N=3e5+5;
std::vectorvec[N];
int du[N];
int n,k,cnt;
bool vis[N];

void dfs(int x){
    vis[x]=true;
    cnt++;
    std::cout<>n>>k;
    for(int i=1;i>u>>v;
        vec[u].push_back(v);
        vec[v].push_back(u);
        du[u]++;
        du[v]++;
    }
    if(n==1) std::cout<<1<<'\n';
    else{
        int st=-1;
        for(int i=1;i<=n;i++){
            if(du[i]==1){
                st=i;
                break;
            }
        }
        dfs(st);
    }
	return 0;
}

os:怎么说呢,还是有些思维在的,,,虽然加了一个DFS,,,

总结:我觉得补的这几个中有些应该是可以想出来的,但是很遗憾没有,说明思维能力还是不够,看到题意没法转化成另一种方式去思考;再者就是对于基础算法的掌握不够熟练,比如D题的DP,没有考虑到DP怎样优化,其实这几个题从题意来说还是从算法难度来说并不困难,需要反思,以后要多练习,作为主机手应该再练习代码能力,思维也需要进一步提高。

若有错误请指教orzorz

你可能感兴趣的:(补题专栏,c++,贪心算法,算法)