我並不會這題,但有個怎麼看都是錯的方法卻能通過:
直接輸出 $C(N,3) - \sum(C(k_i,3))$,若這個值小於 0 則是 IMPOSSIBLE。
但例如說這樣的測資:
4
2
3 3
在歐式幾何公里的假設根本不可能存在只有 4 個點,但有 2 組三點貢獻,答案應該要是 IMPOSSIBLE,但程式碼輸出 2 卻能通過。這題好難啊,真的能好好判斷在給定的共線組合下,至少有多少點嗎?
我並不會這題,但有個怎麼看都是錯的方法卻能通過:
直接輸出 $C(N,3) - \sum(C(k_i,3))$,若這個值小於 0 則是 IMPOSSIBLE。
但例如說這樣的測資:
4
2
3 3
在歐式幾何公里的假設根本不可能存在只有 4 個點,但有 2 組三點貢獻,答案應該要是 IMPOSSIBLE,但程式碼輸出 2 卻能通過。這題好難啊,真的能好好判斷在給定的共線組合下,至少有多少點嗎?
[TIOJ 1347 希爾伯特的書架]
Submission 406621 和 406622 都獲得 AC,實際上為假解,無法通過以下此筆測資:
10 41 12
46 31 3 37 14 42 14 35 20 40
42 20 27 22 46 2 14 33 2
正確答案應為 158056385568438181
,但以上兩個 submission 的 code 輸出結果為 158056385568438182
。
經過 debug 後發現原因為某些大整數轉成double
型態比較時會有精度問題,例如:
//c++
(double)(1LL<<53) == (double)((1LL<<53)+1) //true
此問題可以將double
改為long double
或__float128
解決,即 Submission 406620 的 code。然而 128 bit 浮點數的計算時間比較久,此題時限很緊,會吃 TLE。
看了一些網路上其他 AC 的人的 code,發現也無法通過上述測資。不知道此題是否有其他能在時限內 AC 的解法? 若沒有,是否考慮把時限設大一點讓 128 bit 浮點數計算的解法能 AC 呢?
P.S. 正確答案我是將上述 submission 的 code 轉成python
作為依據,畢竟它能直接作大整數運算,就沒有浮點數精度問題了。
為什麼會RE?
在本地範測是能通過的,但提交後就完全RE了。理論上來說,是不可能出現RE的情況的。
我甚至把包括輸入後面的所有部分全部註釋掉了,還是會RE。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=2e7+10;
const ll INF=1e18;
struct edge
{
int u,v,w,nxt;
}e[N<<1];
int head[N],tot;
void add(int u,int v,int w)
{
e[++tot]=edge{u,v,w,head[u]};
head[u]=tot;
}
int n;
int a[N],b[N];
map<int,int> mp;
int idx;
void init(int p)
{
int x=a[p];
for(int i=2;i<=sqrt(x);i++)
if(x%i==0)
{
if(!mp[i]) mp[i]=++idx;
add(p,mp[i],0),add(mp[i],p,b[p]);
while(x%i==0) x/=i;
}
if(x>1)
{
if(!mp[x]) mp[x]=++idx;
add(p,mp[x],0),add(mp[x],p,b[p]);
}
}
ll dis[N],vis[N];
priority_queue<pair<ll,int> > q;
void dij()
{
for(int i=1;i<=idx;i++) dis[i]=INF;
q.push({0,0});
while(!q.empty())
{
int u=q.top().second;
q.pop();
if(vis[u]) continue;
vis[u]=1;
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].v;ll w=e[i].w;
if(dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
if(!vis[v]) q.push({-dis[v],v});
}
}
}
}
ll calc(int p)
{
int x=a[p];ll res=INF;
for(int i=2;i<=sqrt(x);i++)
if(x%i==0)
{
res=min(res,dis[mp[i]]);
while(x%i==0) x/=i;
}
if(x>1) res=min(res,dis[mp[x]]);
if(res==INF) return -1;
return res;
}
int main()
{
printf(">_<");
// scanf("%d",&n),idx=n+1;
// for(int i=1;i<=n;i++) scanf("%d",&a[i]);
// for(int i=1;i<=n;i++) scanf("%d",&b[i]);
// scanf("%d",&a[0]);
// for(int i=0;i<=n;i++) init(i);
// dij();
// for(int i=1;i<=n;i++) printf("%lld ",calc(i));
return 0;
}
範例2若輸出3 2 1應該也是對的,但上傳後被判wrong answer
原本題目的 checker 沒有設定好,現已修正。
已更新連結
Sample Output 3 should be 35?
連結要從 https://tioj.ck.tp.edu.tw/problems/showproblem?problem_id=1387 改成 https://tioj.ck.tp.edu.tw/problems/1387 才能用。
已修正。
Input Format 中的子任務分數有誤
請仔細閱讀題目敘述。
看不出來這題切了什麼 subtask
aaaba
應該要是 aaabaa
雖然好像原始 pdf 就是打錯的
Comments:
#1 全域陣列的大小導致記憶體用量太多
記憶體用量太多也可能造成 RE。請參照:
https://tioj.ck.tp.edu.tw/about/verdicts
https://tioj.ck.tp.edu.tw/about/memory