10月25日比赛
T1
找规律,感觉很恶心,实际上不难(因为大样例错了?)
总的就是往外围六边型,然后就可以发现一些规律。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll k[1000077];
int main() {
int n,ans = 0,tot = 1;
cin>>n;
for(int i = 1;i <= 20000;++ i) {
k[++tot] = ((((i+i)*(i+i+1)/2)-((i)*(i+1)/2))*2+i+i+1);
}
ll pos = lower_bound(k+1,k+tot+1,n)-k;
cout<<pos*6;
return 0;
}
T2
题目好难懂,写的时候费劲。
真心没有把这个联系到图论上,问zbq学长,他的回答是:“怎么想到图论的就跟怎么想到正解的一个样”。
然后赛时打的暴力,不过思路错啦,赛后改过来了。
#include<bits/stdc++.h>
#define ll long long
#define int long long
using namespace std;
int read() {
int x = 0,f = 1; char c = getchar();
while(c < '0'||c > '9') {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
return x*f;
}
struct op{
int f,c,d,a;
}v[1000077],g[1000077];
int n,nm[1000077];
ll ans;
void dfs(int k) {
if(k==n+1) {
for(int i = 1;i <= n;++ i) v[i] = g[i];
ll res = 0;
for(int i = 1;i <= n;++ i) {
if(nm[i]) {
res += 1ll*v[v[i].f].a*(v[v[i].f].d-v[i].c);
v[v[i].f].a = 0;
}
}
ans = max(ans,res);
return ;
}
for(int i = 0;i <= 1;++ i) {
nm[k] = i;
dfs(k+1);
}
}
signed main() {
// freopen("dundundun.in","r",stdin);
// freopen("dundundun.out","w",stdout);
cin>>n;
int bj1 = 1,bj2=1,bj3=1;
for(int i = 1;i <= n;++ i) {
v[i].f=read();v[i].c=read();v[i].d=read();v[i].a=read();
g[i] = v[i];
if(v[i].f!=i) bj1=0;
if(v[i].a!=1) bj3=0;
}
if(bj1) {
for(int i = 1;i <= n;++ i) {
if(v[i].d-v[i].c > 0) ans += 1ll*(v[i].d-v[i].c)*v[i].a;
}
cout<<ans;
return 0;
}
if(bj3) {
dfs(1);
cout<<ans;
return 0;
}
dfs(1);
cout<<ans;
return 0;
}
T3
并不会正解,zbq学长也说了,这个属于最难得一个题了,所以就打了暴力,按理来说这个暴力复杂度应该可以拿很多分,不过因为某些特殊的字符串导致答案会出现错误,于是就30分了。
#include<bits/stdc++.h>
using namespace std;
string s,g,h;
bool chck() {
int k = h.find(g);
while(k != -1) {
h.erase(k,g.size());
k = h.find(g);
}
return h=="";
}
int main() {
int t;
cin>>t;
while(t--) {
cin>>s;
g = "";
int bj = 0,n = s.size();
for(int len = 0;len < n;++ len) {
for(int i = 0;i+len < n;++ i) {
int j = i+len;
g = s.substr(i,len+1);
h = s;
h.erase(i,len+1);
if(chck()) {
bj = 1;
cout<<g<<'\n';
break;
}
}
if(bj) break;
}
}
return 0;
}
T4
很容易就想到了n3的做法,不过刚开始题目比较难理解,n3有60分,我很高兴的写完了,一
遍过了大样例,但很可惜大样例太弱了,枚举的地方错了没看出来,于是就挂成15了。
#include<bits/stdc++.h>
#include <endian.h>
#define ll long long
using namespace std;
int read() {
int x = 0,f = 1; char c = getchar();
while(c < '0'||c > '9') {if(c=='-')f=-1;c = getchar();}
while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+(c^48);c = getchar();}
return x*f;
}
struct op{
int to,nxt,ds;
}e[1000001];
int head[1000001],num;
void add(int frm,int to,int ds) {
e[++num] = op{to,head[frm],ds};
head[frm] = num;
}
int n,a,m,C;
struct opp{
int diss;
int wz;
bool operator <(const opp&jk) const {
return jk.diss<diss;
}
};
int ds[100001],uot[100001],f[1007][1007],h[1007][1007];
bool vis[100001];
priority_queue<opp>q;
void dij(int s) {
memset(ds,0x3f,sizeof ds);
q.push(opp{0,s}); ds[s] = 0;
while(!q.empty()) {
int x = q.top().wz; q.pop();
if(vis[x]) continue; vis[x] = 1;
for(int i = head[x];i;i = e[i].nxt) {
int v = e[i].to;
if(ds[v] > ds[x]+e[i].ds) {
ds[v] = ds[x]+e[i].ds;
q.push(opp{ds[v],v});
}
}
}
}
ll ans=1e18;
int main() {
cin>>n>>m>>C;
for(int i = 1;i <= m;++ i) {
int u=read(),v=read(),w=read();
add(u,v,w);
add(v,u,w);
f[u][v] = f[v][u] = w;
h[u][v] = h[v][u] = w;
}
dij(1);
int mx = -1;
for(int i = 1;i <= n;++ i) mx = max(mx,ds[i]);
for(int lim = 1;lim <= mx;++ lim) {
int top = 0;
for(int i = 1;i <= n;++ i) if(ds[i] <= lim) uot[++top] = i;
ll res = 0;
for(int i = 1;i <= top;++ i) {
for(int j = 1;j <= top;++ j) {
f[uot[i]][uot[j]] = 0;
}
}
for(int i = 1;i <= n;++ i) {
for(int j = 1;j <= n;++ j) {
res += f[i][j];
f[i][j] = h[i][j];
}
}
ans = min(ans,(res>>1)+C*lim);
}
cout<<ans;
return 0;
}